(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:
lotodore
2007-07-24 14:55:14 +00:00
parent 561b974cdc
commit bd08245c1c
10 changed files with 146 additions and 60 deletions
+25 -11
View File
@@ -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. ]
+3 -3
View File
@@ -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;
+21 -4
View File
@@ -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;
} }
+15 -10
View File
@@ -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 &
+46 -10
View File
@@ -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
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
+15 -4
View File
@@ -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);
+8 -13
View File
@@ -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
View File
@@ -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();
+1 -1
View File
@@ -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);
+1
View File
@@ -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