(Hopefully) solved the player number problem, when players join and leave an existing game. Numbers are now assigned on game start, not before. Note: Network play is not compatible to the current official version.
This commit is contained in:
+25
-11
@@ -1,3 +1,9 @@
|
|||||||
|
Changelog:
|
||||||
|
07-24-2007: Join Game ACK / Player Joined do not specify player number.
|
||||||
|
Player order is transferred on game start.
|
||||||
|
This is not compatible to the previous protocol.
|
||||||
|
|
||||||
|
|
||||||
PokerTH general message format:
|
PokerTH general message format:
|
||||||
|
|
||||||
0 1 2 3
|
0 1 2 3
|
||||||
@@ -59,19 +65,15 @@ Server Reply: Join Game ACK
|
|||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
| Your Session ID |
|
| Your Session ID |
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
| Your Player ID | Your Player Number |
|
| Your Player ID | Max Number of Players |
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
| Max Number of Players | Small Blind |
|
| Small Blind | Hands before raise |
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
| Hands before raise | Proposed GUI Speed |
|
| Proposed GUI Speed | Player Action Timeout |
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
||||||
| Player Action Timeout | Reserved |
|
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
| Start Money |
|
| Start Money |
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
|
||||||
Player Number:
|
|
||||||
0 to (NumberOfPlayers - 1), "position".
|
|
||||||
Player ID:
|
Player ID:
|
||||||
Unique Player ID
|
Unique Player ID
|
||||||
Proposed GUI Speed:
|
Proposed GUI Speed:
|
||||||
@@ -87,9 +89,9 @@ Server Notification: Player Joined
|
|||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
| Message Type = 3 | Message Length |
|
| Message Type = 3 | Message Length |
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
| Player ID | Player Number |
|
| Player ID | Player Flags |
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
| Player Flags | Name Length |
|
| Name Length | Reserved |
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
| \
|
| \
|
||||||
\ Name (UTF-8) /
|
\ Name (UTF-8) /
|
||||||
@@ -105,7 +107,7 @@ Server Notification: Player Left
|
|||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
| Message Type = 4 | Message Length = 8 |
|
| Message Type = 4 | Message Length = 8 |
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
| Player ID | Reserved |
|
| Player ID | Reserved |
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
|
||||||
|
|
||||||
@@ -114,10 +116,22 @@ Server Notification: Game Start
|
|||||||
0 1 2 3
|
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
|
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 = 5 | Message Length = 8 |
|
| Message Type = 5 | Message Length |
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
| Start Dealer Player Id | Number of Players |
|
| Start Dealer Player Id | Number of Players |
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
| Player ID Slot #1 | Player ID Slot #2 |
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
| \
|
||||||
|
\ Additional Player Slots /
|
||||||
|
/ |
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
| Player ID Slot #n | Padding |
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
|
||||||
|
The player slots are the positions of the players on the table. Each slot
|
||||||
|
contains the ID for the corresponding player. The slots are ordered.
|
||||||
|
The number of player slots is the number of players.
|
||||||
|
|
||||||
[ Dealer Pos can be different for each game, therefore it is not
|
[ Dealer Pos can be different for each game, therefore it is not
|
||||||
transmitted in Join Game ACK. ]
|
transmitted in Join Game ACK. ]
|
||||||
|
|||||||
@@ -77,8 +77,8 @@ protected:
|
|||||||
void SetGameData(const GameData &gameData);
|
void SetGameData(const GameData &gameData);
|
||||||
const StartData &GetStartData() const;
|
const StartData &GetStartData() const;
|
||||||
void SetStartData(const StartData &startData);
|
void SetStartData(const StartData &startData);
|
||||||
int GetGuiPlayerNum() const;
|
int GetGuiPlayerId() const;
|
||||||
void SetGuiPlayerNum(int guiPlayerNum);
|
void SetGuiPlayerId(int guiPlayerId);
|
||||||
|
|
||||||
boost::shared_ptr<Game> GetGame();
|
boost::shared_ptr<Game> GetGame();
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@ private:
|
|||||||
boost::shared_ptr<Game> m_game;
|
boost::shared_ptr<Game> m_game;
|
||||||
|
|
||||||
unsigned m_curGameId;
|
unsigned m_curGameId;
|
||||||
int m_guiPlayerNum;
|
unsigned m_guiPlayerId;
|
||||||
|
|
||||||
friend class AbstractClientStateReceiving;
|
friend class AbstractClientStateReceiving;
|
||||||
friend class ClientStateInit;
|
friend class ClientStateInit;
|
||||||
|
|||||||
@@ -443,11 +443,12 @@ ClientStateWaitSession::InternalProcess(ClientThread &client, boost::shared_ptr<
|
|||||||
NetPacketJoinGameAck::Data joinGameAckData;
|
NetPacketJoinGameAck::Data joinGameAckData;
|
||||||
packet->ToNetPacketJoinGameAck()->GetData(joinGameAckData);
|
packet->ToNetPacketJoinGameAck()->GetData(joinGameAckData);
|
||||||
client.SetGameData(joinGameAckData.gameData);
|
client.SetGameData(joinGameAckData.gameData);
|
||||||
client.SetGuiPlayerNum(joinGameAckData.yourPlayerNum);
|
client.SetGuiPlayerId(joinGameAckData.yourPlayerUniqueId);
|
||||||
|
|
||||||
// TODO: Type Human is fixed here.
|
// TODO: Type Human is fixed here.
|
||||||
|
// Player number is 0 on join. Will be set when the game starts.
|
||||||
boost::shared_ptr<PlayerData> playerData(
|
boost::shared_ptr<PlayerData> playerData(
|
||||||
new PlayerData(joinGameAckData.yourPlayerUniqueId, joinGameAckData.yourPlayerNum, PLAYER_TYPE_HUMAN));
|
new PlayerData(joinGameAckData.yourPlayerUniqueId, 0, PLAYER_TYPE_HUMAN));
|
||||||
playerData->SetName(context.GetPlayerName());
|
playerData->SetName(context.GetPlayerName());
|
||||||
client.AddPlayerData(playerData);
|
client.AddPlayerData(playerData);
|
||||||
|
|
||||||
@@ -489,6 +490,23 @@ ClientStateWaitGame::InternalProcess(ClientThread &client, boost::shared_ptr<Net
|
|||||||
|
|
||||||
client.SetStartData(gameStartData.startData);
|
client.SetStartData(gameStartData.startData);
|
||||||
|
|
||||||
|
// Set player numbers using the game start data slots.
|
||||||
|
NetPacketGameStart::PlayerSlotList::const_iterator slot_i = gameStartData.playerSlots.begin();
|
||||||
|
NetPacketGameStart::PlayerSlotList::const_iterator slot_end = gameStartData.playerSlots.end();
|
||||||
|
int num = 0;
|
||||||
|
|
||||||
|
while (slot_i != slot_end)
|
||||||
|
{
|
||||||
|
unsigned playerId = (*slot_i).playerId;
|
||||||
|
boost::shared_ptr<PlayerData> tmpPlayer = client.GetPlayerDataByUniqueId(playerId);
|
||||||
|
if (!tmpPlayer.get())
|
||||||
|
throw ClientException(ERR_NET_UNKNOWN_PLAYER_ID, 0);
|
||||||
|
tmpPlayer->SetNumber(num);
|
||||||
|
|
||||||
|
++num;
|
||||||
|
++slot_i;
|
||||||
|
}
|
||||||
|
|
||||||
client.SetState(ClientStateWaitHand::Instance());
|
client.SetState(ClientStateWaitHand::Instance());
|
||||||
retVal = MSG_NET_GAME_CLIENT_START;
|
retVal = MSG_NET_GAME_CLIENT_START;
|
||||||
}
|
}
|
||||||
@@ -499,11 +517,10 @@ ClientStateWaitGame::InternalProcess(ClientThread &client, boost::shared_ptr<Net
|
|||||||
packet->ToNetPacketPlayerJoined()->GetData(netPlayerData);
|
packet->ToNetPacketPlayerJoined()->GetData(netPlayerData);
|
||||||
|
|
||||||
boost::shared_ptr<PlayerData> playerData(
|
boost::shared_ptr<PlayerData> playerData(
|
||||||
new PlayerData(netPlayerData.playerId, netPlayerData.playerNumber, netPlayerData.ptype));
|
new PlayerData(netPlayerData.playerId, 0, netPlayerData.ptype));
|
||||||
playerData->SetName(netPlayerData.playerName);
|
playerData->SetName(netPlayerData.playerName);
|
||||||
client.AddPlayerData(playerData);
|
client.AddPlayerData(playerData);
|
||||||
}
|
}
|
||||||
// TODO: handle error packet (kicked from server)
|
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
ClientThread::ClientThread(GuiInterface &gui)
|
ClientThread::ClientThread(GuiInterface &gui)
|
||||||
: m_curState(NULL), m_gui(gui), m_curGameId(1), m_guiPlayerNum(0)
|
: m_curState(NULL), m_gui(gui), m_curGameId(1), m_guiPlayerId(0)
|
||||||
{
|
{
|
||||||
m_context.reset(new ClientContext);
|
m_context.reset(new ClientContext);
|
||||||
m_senderCallback.reset(new ClientSenderCallback(*this));
|
m_senderCallback.reset(new ClientSenderCallback(*this));
|
||||||
@@ -244,15 +244,15 @@ ClientThread::SetStartData(const StartData &startData)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ClientThread::GetGuiPlayerNum() const
|
ClientThread::GetGuiPlayerId() const
|
||||||
{
|
{
|
||||||
return m_guiPlayerNum;
|
return m_guiPlayerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ClientThread::SetGuiPlayerNum(int guiPlayerNum)
|
ClientThread::SetGuiPlayerId(int guiPlayerId)
|
||||||
{
|
{
|
||||||
m_guiPlayerNum = guiPlayerNum;
|
m_guiPlayerId = guiPlayerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<Game>
|
boost::shared_ptr<Game>
|
||||||
@@ -303,21 +303,27 @@ ClientThread::RemovePlayerData(unsigned playerId)
|
|||||||
void
|
void
|
||||||
ClientThread::MapPlayerDataList()
|
ClientThread::MapPlayerDataList()
|
||||||
{
|
{
|
||||||
|
// Retrieve the GUI player.
|
||||||
|
boost::shared_ptr<PlayerData> guiPlayer = GetPlayerDataByUniqueId(GetGuiPlayerId());
|
||||||
|
assert(guiPlayer.get());
|
||||||
|
int guiPlayerNum = guiPlayer->GetNumber();
|
||||||
|
|
||||||
|
// Create a copy of the player list so that the GUI player
|
||||||
|
// is player 0. This is mapped because the GUI depends on it.
|
||||||
PlayerDataList mappedList;
|
PlayerDataList mappedList;
|
||||||
|
|
||||||
PlayerDataList::const_iterator i = m_playerDataList.begin();
|
PlayerDataList::const_iterator i = m_playerDataList.begin();
|
||||||
PlayerDataList::const_iterator end = m_playerDataList.end();
|
PlayerDataList::const_iterator end = m_playerDataList.end();
|
||||||
|
int numPlayers = GetStartData().numberOfPlayers;
|
||||||
|
|
||||||
// Create a copy of the player list so that the GUI player
|
|
||||||
// is player 0. This is mapped because the GUI depends on it.
|
|
||||||
while (i != end)
|
while (i != end)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<PlayerData> tmpData(new PlayerData(*(*i)));
|
boost::shared_ptr<PlayerData> tmpData(new PlayerData(*(*i)));
|
||||||
int numberDiff = tmpData->GetNumber() - GetGuiPlayerNum();
|
int numberDiff = tmpData->GetNumber() - guiPlayerNum;
|
||||||
if (numberDiff >= 0)
|
if (numberDiff >= 0)
|
||||||
tmpData->SetNumber(numberDiff);
|
tmpData->SetNumber(numberDiff);
|
||||||
else
|
else
|
||||||
tmpData->SetNumber(GetStartData().numberOfPlayers + numberDiff);
|
tmpData->SetNumber(numPlayers + numberDiff);
|
||||||
mappedList.push_back(tmpData);
|
mappedList.push_back(tmpData);
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
@@ -326,7 +332,6 @@ ClientThread::MapPlayerDataList()
|
|||||||
mappedList.sort(*boost::lambda::_1 < *boost::lambda::_2);
|
mappedList.sort(*boost::lambda::_1 < *boost::lambda::_2);
|
||||||
|
|
||||||
m_playerDataList = mappedList;
|
m_playerDataList = mappedList;
|
||||||
SetGuiPlayerNum(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const PlayerDataList &
|
const PlayerDataList &
|
||||||
|
|||||||
@@ -93,13 +93,11 @@ struct GCC_PACKED NetPacketJoinGameAckData
|
|||||||
NetPacketHeader head;
|
NetPacketHeader head;
|
||||||
u_int32_t sessionId;
|
u_int32_t sessionId;
|
||||||
u_int16_t playerId;
|
u_int16_t playerId;
|
||||||
u_int16_t playerNumber;
|
|
||||||
u_int16_t maxNumberOfPlayers;
|
u_int16_t maxNumberOfPlayers;
|
||||||
u_int16_t smallBlind;
|
u_int16_t smallBlind;
|
||||||
u_int16_t handsBeforeRaise;
|
u_int16_t handsBeforeRaise;
|
||||||
u_int16_t proposedGuiSpeed;
|
u_int16_t proposedGuiSpeed;
|
||||||
u_int16_t playerActionTimeout;
|
u_int16_t playerActionTimeout;
|
||||||
u_int16_t reserved;
|
|
||||||
u_int32_t startMoney;
|
u_int32_t startMoney;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -114,9 +112,9 @@ struct GCC_PACKED NetPacketPlayerJoinedData
|
|||||||
{
|
{
|
||||||
NetPacketHeader head;
|
NetPacketHeader head;
|
||||||
u_int16_t playerId;
|
u_int16_t playerId;
|
||||||
u_int16_t playerNumber;
|
|
||||||
u_int16_t playerFlags;
|
u_int16_t playerFlags;
|
||||||
u_int16_t playerNameLength;
|
u_int16_t playerNameLength;
|
||||||
|
u_int16_t reserved;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GCC_PACKED NetPacketPlayerLeftData
|
struct GCC_PACKED NetPacketPlayerLeftData
|
||||||
@@ -133,6 +131,11 @@ struct GCC_PACKED NetPacketGameStartData
|
|||||||
u_int16_t numberOfPlayers;
|
u_int16_t numberOfPlayers;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct GCC_PACKED PlayerSlotData
|
||||||
|
{
|
||||||
|
u_int16_t playerId;
|
||||||
|
};
|
||||||
|
|
||||||
struct GCC_PACKED NetPacketHandStartData
|
struct GCC_PACKED NetPacketHandStartData
|
||||||
{
|
{
|
||||||
NetPacketHeader head;
|
NetPacketHeader head;
|
||||||
@@ -736,7 +739,6 @@ NetPacketJoinGameAck::SetData(const NetPacketJoinGameAck::Data &inData)
|
|||||||
|
|
||||||
tmpData->sessionId = htonl(inData.sessionId);
|
tmpData->sessionId = htonl(inData.sessionId);
|
||||||
tmpData->playerId = htons(inData.yourPlayerUniqueId);
|
tmpData->playerId = htons(inData.yourPlayerUniqueId);
|
||||||
tmpData->playerNumber = htons(inData.yourPlayerNum);
|
|
||||||
tmpData->maxNumberOfPlayers = htons(inData.gameData.maxNumberOfPlayers);
|
tmpData->maxNumberOfPlayers = htons(inData.gameData.maxNumberOfPlayers);
|
||||||
tmpData->smallBlind = htons(inData.gameData.smallBlind);
|
tmpData->smallBlind = htons(inData.gameData.smallBlind);
|
||||||
tmpData->handsBeforeRaise = htons(inData.gameData.handsBeforeRaise);
|
tmpData->handsBeforeRaise = htons(inData.gameData.handsBeforeRaise);
|
||||||
@@ -753,7 +755,6 @@ NetPacketJoinGameAck::GetData(NetPacketJoinGameAck::Data &outData) const
|
|||||||
|
|
||||||
outData.sessionId = ntohl(tmpData->sessionId);
|
outData.sessionId = ntohl(tmpData->sessionId);
|
||||||
outData.yourPlayerUniqueId = ntohs(tmpData->playerId);
|
outData.yourPlayerUniqueId = ntohs(tmpData->playerId);
|
||||||
outData.yourPlayerNum = ntohs(tmpData->playerNumber);
|
|
||||||
outData.gameData.maxNumberOfPlayers = ntohs(tmpData->maxNumberOfPlayers);
|
outData.gameData.maxNumberOfPlayers = ntohs(tmpData->maxNumberOfPlayers);
|
||||||
outData.gameData.smallBlind = ntohs(tmpData->smallBlind);
|
outData.gameData.smallBlind = ntohs(tmpData->smallBlind);
|
||||||
outData.gameData.handsBeforeRaise = ntohs(tmpData->handsBeforeRaise);
|
outData.gameData.handsBeforeRaise = ntohs(tmpData->handsBeforeRaise);
|
||||||
@@ -824,7 +825,6 @@ NetPacketPlayerJoined::SetData(const NetPacketPlayerJoined::Data &inData)
|
|||||||
// Set the data.
|
// Set the data.
|
||||||
tmpData->playerFlags = htons((inData.ptype == PLAYER_TYPE_HUMAN) ? NET_PLAYER_FLAG_HUMAN : 0);
|
tmpData->playerFlags = htons((inData.ptype == PLAYER_TYPE_HUMAN) ? NET_PLAYER_FLAG_HUMAN : 0);
|
||||||
tmpData->playerId = htons(inData.playerId);
|
tmpData->playerId = htons(inData.playerId);
|
||||||
tmpData->playerNumber = htons(inData.playerNumber);
|
|
||||||
tmpData->playerNameLength = htons(playerNameLen);
|
tmpData->playerNameLength = htons(playerNameLen);
|
||||||
char *namePtr = (char *)tmpData + sizeof(NetPacketPlayerJoinedData);
|
char *namePtr = (char *)tmpData + sizeof(NetPacketPlayerJoinedData);
|
||||||
memcpy(namePtr, inData.playerName.c_str(), playerNameLen);
|
memcpy(namePtr, inData.playerName.c_str(), playerNameLen);
|
||||||
@@ -839,7 +839,6 @@ NetPacketPlayerJoined::GetData(NetPacketPlayerJoined::Data &outData) const
|
|||||||
|
|
||||||
outData.ptype = (ntohs(tmpData->playerFlags) & NET_PLAYER_FLAG_HUMAN) ? PLAYER_TYPE_HUMAN : PLAYER_TYPE_COMPUTER;
|
outData.ptype = (ntohs(tmpData->playerFlags) & NET_PLAYER_FLAG_HUMAN) ? PLAYER_TYPE_HUMAN : PLAYER_TYPE_COMPUTER;
|
||||||
outData.playerId = ntohs(tmpData->playerId);
|
outData.playerId = ntohs(tmpData->playerId);
|
||||||
outData.playerNumber = ntohs(tmpData->playerNumber);
|
|
||||||
char *namePtr = (char *)tmpData + sizeof(NetPacketPlayerJoinedData);
|
char *namePtr = (char *)tmpData + sizeof(NetPacketPlayerJoinedData);
|
||||||
outData.playerName = string(namePtr, ntohs(tmpData->playerNameLength));
|
outData.playerName = string(namePtr, ntohs(tmpData->playerNameLength));
|
||||||
}
|
}
|
||||||
@@ -969,11 +968,33 @@ NetPacketGameStart::Clone() const
|
|||||||
void
|
void
|
||||||
NetPacketGameStart::SetData(const NetPacketGameStart::Data &inData)
|
NetPacketGameStart::SetData(const NetPacketGameStart::Data &inData)
|
||||||
{
|
{
|
||||||
|
u_int16_t numPlayers = (u_int16_t)inData.playerSlots.size();
|
||||||
|
|
||||||
|
if (!numPlayers || numPlayers > MAX_NUMBER_OF_PLAYERS || numPlayers != inData.startData.numberOfPlayers)
|
||||||
|
throw NetException(ERR_NET_INVALID_PLAYER_COUNT, 0);
|
||||||
|
|
||||||
|
// Resize the packet so that the data fits in.
|
||||||
|
Resize((u_int16_t)
|
||||||
|
(sizeof(NetPacketGameStartData) + ADD_PADDING(numPlayers * sizeof(PlayerSlotData))));
|
||||||
|
|
||||||
NetPacketGameStartData *tmpData = (NetPacketGameStartData *)GetRawData();
|
NetPacketGameStartData *tmpData = (NetPacketGameStartData *)GetRawData();
|
||||||
assert(tmpData);
|
assert(tmpData);
|
||||||
|
|
||||||
tmpData->startDealerPlayerId = htons(inData.startData.startDealerPlayerId);
|
tmpData->startDealerPlayerId = htons(inData.startData.startDealerPlayerId);
|
||||||
tmpData->numberOfPlayers = htons(inData.startData.numberOfPlayers);
|
tmpData->numberOfPlayers = htons(numPlayers);
|
||||||
|
|
||||||
|
PlayerSlotList::const_iterator i = inData.playerSlots.begin();
|
||||||
|
PlayerSlotList::const_iterator end = inData.playerSlots.end();
|
||||||
|
|
||||||
|
// Copy the player slot data to continous memory
|
||||||
|
PlayerSlotData *curPlayerSlotData =
|
||||||
|
(PlayerSlotData *)((char *)tmpData + sizeof(NetPacketGameStartData));
|
||||||
|
while (i != end)
|
||||||
|
{
|
||||||
|
curPlayerSlotData->playerId = htons((*i).playerId);
|
||||||
|
++curPlayerSlotData;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -983,7 +1004,21 @@ NetPacketGameStart::GetData(NetPacketGameStart::Data &outData) const
|
|||||||
assert(tmpData);
|
assert(tmpData);
|
||||||
|
|
||||||
outData.startData.startDealerPlayerId = ntohs(tmpData->startDealerPlayerId);
|
outData.startData.startDealerPlayerId = ntohs(tmpData->startDealerPlayerId);
|
||||||
outData.startData.numberOfPlayers = ntohs(tmpData->numberOfPlayers);
|
u_int16_t numPlayers = ntohs(tmpData->numberOfPlayers);
|
||||||
|
outData.startData.numberOfPlayers = numPlayers;
|
||||||
|
|
||||||
|
PlayerSlotData *curPlayerSlotData =
|
||||||
|
(PlayerSlotData *)((char *)tmpData + sizeof(NetPacketGameStartData));
|
||||||
|
|
||||||
|
// Store all available player slots.
|
||||||
|
for (int i = 0; i < numPlayers; i++)
|
||||||
|
{
|
||||||
|
PlayerSlot tmpPlayerSlot;
|
||||||
|
tmpPlayerSlot.playerId = ntohs(curPlayerSlotData->playerId);
|
||||||
|
|
||||||
|
outData.playerSlots.push_back(tmpPlayerSlot);
|
||||||
|
++curPlayerSlotData;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const NetPacketGameStart *
|
const NetPacketGameStart *
|
||||||
@@ -998,10 +1033,11 @@ NetPacketGameStart::Check(const NetPacketHeader* data) const
|
|||||||
assert(data);
|
assert(data);
|
||||||
|
|
||||||
u_int16_t dataLen = ntohs(data->length);
|
u_int16_t dataLen = ntohs(data->length);
|
||||||
if (dataLen != sizeof(NetPacketGameStartData))
|
if (dataLen < sizeof(NetPacketGameStartData))
|
||||||
{
|
{
|
||||||
throw NetException(ERR_SOCK_INVALID_PACKET, 0);
|
throw NetException(ERR_SOCK_INVALID_PACKET, 0);
|
||||||
}
|
}
|
||||||
|
// TODO additional checking
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -290,7 +290,7 @@ ServerRecvStateInit::InternalProcess(ServerRecvThread &server, SessionWrapper se
|
|||||||
|
|
||||||
// Create player data object.
|
// Create player data object.
|
||||||
boost::shared_ptr<PlayerData> tmpPlayerData(
|
boost::shared_ptr<PlayerData> tmpPlayerData(
|
||||||
new PlayerData(m_curUniquePlayerId++, server.GetNextPlayerNumber(), joinGameData.ptype));
|
new PlayerData(m_curUniquePlayerId++, 0, joinGameData.ptype));
|
||||||
tmpPlayerData->SetName(joinGameData.playerName);
|
tmpPlayerData->SetName(joinGameData.playerName);
|
||||||
tmpPlayerData->SetNetSessionData(session.sessionData);
|
tmpPlayerData->SetNetSessionData(session.sessionData);
|
||||||
|
|
||||||
@@ -299,7 +299,6 @@ ServerRecvStateInit::InternalProcess(ServerRecvThread &server, SessionWrapper se
|
|||||||
NetPacketJoinGameAck::Data joinGameAckData;
|
NetPacketJoinGameAck::Data joinGameAckData;
|
||||||
joinGameAckData.sessionId = session.sessionData->GetId(); // TODO: currently unused.
|
joinGameAckData.sessionId = session.sessionData->GetId(); // TODO: currently unused.
|
||||||
joinGameAckData.yourPlayerUniqueId = tmpPlayerData->GetUniqueId();
|
joinGameAckData.yourPlayerUniqueId = tmpPlayerData->GetUniqueId();
|
||||||
joinGameAckData.yourPlayerNum = tmpPlayerData->GetNumber();
|
|
||||||
joinGameAckData.gameData = server.GetGameData();
|
joinGameAckData.gameData = server.GetGameData();
|
||||||
static_cast<NetPacketJoinGameAck *>(answer.get())->SetData(joinGameAckData);
|
static_cast<NetPacketJoinGameAck *>(answer.get())->SetData(joinGameAckData);
|
||||||
server.GetSender().Send(session.sessionData->GetSocket(), answer);
|
server.GetSender().Send(session.sessionData->GetSocket(), answer);
|
||||||
@@ -314,7 +313,6 @@ ServerRecvStateInit::InternalProcess(ServerRecvThread &server, SessionWrapper se
|
|||||||
NetPacketPlayerJoined::Data otherPlayerJoinedData;
|
NetPacketPlayerJoined::Data otherPlayerJoinedData;
|
||||||
otherPlayerJoinedData.playerId = (*player_i)->GetUniqueId();
|
otherPlayerJoinedData.playerId = (*player_i)->GetUniqueId();
|
||||||
otherPlayerJoinedData.playerName = (*player_i)->GetName();
|
otherPlayerJoinedData.playerName = (*player_i)->GetName();
|
||||||
otherPlayerJoinedData.playerNumber = (*player_i)->GetNumber();
|
|
||||||
otherPlayerJoinedData.ptype = (*player_i)->GetType();
|
otherPlayerJoinedData.ptype = (*player_i)->GetType();
|
||||||
static_cast<NetPacketPlayerJoined *>(otherPlayerJoined.get())->SetData(otherPlayerJoinedData);
|
static_cast<NetPacketPlayerJoined *>(otherPlayerJoined.get())->SetData(otherPlayerJoinedData);
|
||||||
server.GetSender().Send(session.sessionData->GetSocket(), otherPlayerJoined);
|
server.GetSender().Send(session.sessionData->GetSocket(), otherPlayerJoined);
|
||||||
@@ -327,7 +325,6 @@ ServerRecvStateInit::InternalProcess(ServerRecvThread &server, SessionWrapper se
|
|||||||
NetPacketPlayerJoined::Data thisPlayerJoinedData;
|
NetPacketPlayerJoined::Data thisPlayerJoinedData;
|
||||||
thisPlayerJoinedData.playerId = tmpPlayerData->GetUniqueId();
|
thisPlayerJoinedData.playerId = tmpPlayerData->GetUniqueId();
|
||||||
thisPlayerJoinedData.playerName = tmpPlayerData->GetName();
|
thisPlayerJoinedData.playerName = tmpPlayerData->GetName();
|
||||||
thisPlayerJoinedData.playerNumber = tmpPlayerData->GetNumber();
|
|
||||||
thisPlayerJoinedData.ptype = tmpPlayerData->GetType();
|
thisPlayerJoinedData.ptype = tmpPlayerData->GetType();
|
||||||
static_cast<NetPacketPlayerJoined *>(thisPlayerJoined.get())->SetData(thisPlayerJoinedData);
|
static_cast<NetPacketPlayerJoined *>(thisPlayerJoined.get())->SetData(thisPlayerJoinedData);
|
||||||
server.SendToAllPlayers(thisPlayerJoined);
|
server.SendToAllPlayers(thisPlayerJoined);
|
||||||
@@ -382,6 +379,20 @@ ServerRecvStateStartGame::Process(ServerRecvThread &server)
|
|||||||
|
|
||||||
NetPacketGameStart::Data gameStartData;
|
NetPacketGameStart::Data gameStartData;
|
||||||
gameStartData.startData = server.GetStartData();
|
gameStartData.startData = server.GetStartData();
|
||||||
|
|
||||||
|
// Assign player numbers. Assume Player List is sorted by number.
|
||||||
|
PlayerDataList tmpPlayerList = server.GetPlayerDataList();
|
||||||
|
PlayerDataList::iterator player_i = tmpPlayerList.begin();
|
||||||
|
PlayerDataList::iterator player_end = tmpPlayerList.end();
|
||||||
|
while (player_i != player_end)
|
||||||
|
{
|
||||||
|
NetPacketGameStart::PlayerSlot tmpPlayerSlot;
|
||||||
|
tmpPlayerSlot.playerId = (*player_i)->GetUniqueId();
|
||||||
|
gameStartData.playerSlots.push_back(tmpPlayerSlot);
|
||||||
|
|
||||||
|
++player_i;
|
||||||
|
}
|
||||||
|
|
||||||
static_cast<NetPacketGameStart *>(answer.get())->SetData(gameStartData);
|
static_cast<NetPacketGameStart *>(answer.get())->SetData(gameStartData);
|
||||||
|
|
||||||
server.SendToAllPlayers(answer);
|
server.SendToAllPlayers(answer);
|
||||||
|
|||||||
@@ -253,6 +253,8 @@ ServerRecvThread::InternalStartGame()
|
|||||||
|
|
||||||
// Kick all players which are not fully connected.
|
// Kick all players which are not fully connected.
|
||||||
RemoveNotEstablishedSessions();
|
RemoveNotEstablishedSessions();
|
||||||
|
// Set order of players.
|
||||||
|
AssignPlayerNumbers();
|
||||||
|
|
||||||
// Initialize the game.
|
// Initialize the game.
|
||||||
GuiInterface &gui = GetGui();
|
GuiInterface &gui = GetGui();
|
||||||
@@ -559,31 +561,24 @@ ServerRecvThread::GetPlayerDataList() const
|
|||||||
}
|
}
|
||||||
++session_i;
|
++session_i;
|
||||||
}
|
}
|
||||||
// Sort the list by player number.
|
|
||||||
playerList.sort(*boost::lambda::_1 < *boost::lambda::_2);
|
|
||||||
return playerList;
|
return playerList;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
ServerRecvThread::GetNextPlayerNumber() const
|
ServerRecvThread::AssignPlayerNumbers()
|
||||||
{
|
{
|
||||||
int playerNumber = 0;
|
int playerNumber = 0;
|
||||||
|
|
||||||
PlayerDataList playerList = GetPlayerDataList();
|
PlayerDataList playerList = GetPlayerDataList();
|
||||||
PlayerDataList::const_iterator player_i = playerList.begin();
|
PlayerDataList::iterator player_i = playerList.begin();
|
||||||
PlayerDataList::const_iterator player_end = playerList.end();
|
PlayerDataList::iterator player_end = playerList.end();
|
||||||
|
|
||||||
// Assume the player list is sorted by player number.
|
|
||||||
while (player_i != player_end)
|
while (player_i != player_end)
|
||||||
{
|
{
|
||||||
if ((*player_i)->GetNumber() == playerNumber)
|
(*player_i)->SetNumber(playerNumber);
|
||||||
playerNumber++;
|
++playerNumber;
|
||||||
else
|
|
||||||
break;
|
|
||||||
++player_i;
|
++player_i;
|
||||||
}
|
}
|
||||||
|
|
||||||
return playerNumber;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
+11
-4
@@ -26,7 +26,7 @@
|
|||||||
#include <gamedata.h>
|
#include <gamedata.h>
|
||||||
#include <net/socket_helper.h>
|
#include <net/socket_helper.h>
|
||||||
|
|
||||||
#define NET_VERSION_MAJOR 1
|
#define NET_VERSION_MAJOR 2
|
||||||
#define NET_VERSION_MINOR 0
|
#define NET_VERSION_MINOR 0
|
||||||
|
|
||||||
#define MIN_PACKET_SIZE 4
|
#define MIN_PACKET_SIZE 4
|
||||||
@@ -143,7 +143,6 @@ public:
|
|||||||
struct Data
|
struct Data
|
||||||
{
|
{
|
||||||
u_int32_t sessionId;
|
u_int32_t sessionId;
|
||||||
int16_t yourPlayerNum;
|
|
||||||
u_int16_t yourPlayerUniqueId;
|
u_int16_t yourPlayerUniqueId;
|
||||||
GameData gameData;
|
GameData gameData;
|
||||||
};
|
};
|
||||||
@@ -169,7 +168,6 @@ public:
|
|||||||
struct Data
|
struct Data
|
||||||
{
|
{
|
||||||
u_int16_t playerId;
|
u_int16_t playerId;
|
||||||
u_int16_t playerNumber;
|
|
||||||
PlayerType ptype;
|
PlayerType ptype;
|
||||||
std::string playerName;
|
std::string playerName;
|
||||||
};
|
};
|
||||||
@@ -215,9 +213,18 @@ protected:
|
|||||||
class NetPacketGameStart : public NetPacket
|
class NetPacketGameStart : public NetPacket
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
struct PlayerSlot
|
||||||
|
{
|
||||||
|
unsigned playerId;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::list<PlayerSlot> PlayerSlotList;
|
||||||
|
|
||||||
struct Data
|
struct Data
|
||||||
{
|
{
|
||||||
StartData startData;
|
StartData startData;
|
||||||
|
PlayerSlotList playerSlots;
|
||||||
};
|
};
|
||||||
|
|
||||||
NetPacketGameStart();
|
NetPacketGameStart();
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ protected:
|
|||||||
void SetSessionPlayerData(boost::shared_ptr<SessionData> sessionData, boost::shared_ptr<PlayerData> playerData);
|
void SetSessionPlayerData(boost::shared_ptr<SessionData> sessionData, boost::shared_ptr<PlayerData> playerData);
|
||||||
PlayerDataList GetPlayerDataList() const;
|
PlayerDataList GetPlayerDataList() const;
|
||||||
|
|
||||||
int GetNextPlayerNumber() const;
|
void AssignPlayerNumbers();
|
||||||
|
|
||||||
ServerRecvState &GetState();
|
ServerRecvState &GetState();
|
||||||
void SetState(ServerRecvState &newState);
|
void SetState(ServerRecvState &newState);
|
||||||
|
|||||||
@@ -55,6 +55,7 @@
|
|||||||
#define ERR_NET_INVALID_ROUND 112
|
#define ERR_NET_INVALID_ROUND 112
|
||||||
#define ERR_NET_PLAYER_KICKED 113
|
#define ERR_NET_PLAYER_KICKED 113
|
||||||
#define ERR_NET_INVALID_PLAYER_COUNT 114
|
#define ERR_NET_INVALID_PLAYER_COUNT 114
|
||||||
|
#define ERR_NET_PLAYER_NOT_IN_GAME 115
|
||||||
|
|
||||||
// This is an internal message which is not reported.
|
// This is an internal message which is not reported.
|
||||||
#define MSG_SOCK_INTERNAL_PENDING 0
|
#define MSG_SOCK_INTERNAL_PENDING 0
|
||||||
|
|||||||
Reference in New Issue
Block a user