Synchronize on network game start, so that everyone has received all avatars and player names before the game starts. Store all computer players in a separate list on the server for name retrieval.
This commit is contained in:
+14
-1
@@ -427,7 +427,7 @@ Client Request: Leave Current Game
|
|||||||
(will be answered with a Server Notification: Removed From Game)
|
(will be answered with a Server Notification: Removed From Game)
|
||||||
|
|
||||||
|
|
||||||
Client Request: Start Event
|
Client Request/Server Request: Start Event
|
||||||
|
|
||||||
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
|
||||||
@@ -436,10 +436,23 @@ Client Request: Start Event
|
|||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
| Start Flags | Reserved |
|
| Start Flags | Reserved |
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
(sent by one client, repeated to everyone by the server)
|
||||||
Start Flags:
|
Start Flags:
|
||||||
0x01 set: Fill up with computer opponents.
|
0x01 set: Fill up with computer opponents.
|
||||||
|
|
||||||
|
|
||||||
|
Client Reply: Start Event 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 = 67 | Message Length = 8 |
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
| Reserved |
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
(every client must confirm the start event)
|
||||||
|
|
||||||
|
|
||||||
Server Notification: Game Start
|
Server Notification: Game Start
|
||||||
|
|
||||||
0 1 2 3
|
0 1 2 3
|
||||||
|
|||||||
@@ -234,6 +234,41 @@ protected:
|
|||||||
virtual int InternalProcess(ClientThread &client, boost::shared_ptr<NetPacket> packet);
|
virtual int InternalProcess(ClientThread &client, boost::shared_ptr<NetPacket> packet);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// State: Synchronize on game start.
|
||||||
|
class ClientStateSynchronizeStart : public AbstractClientStateReceiving
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Access the state singleton.
|
||||||
|
static ClientStateSynchronizeStart &Instance();
|
||||||
|
|
||||||
|
virtual ~ClientStateSynchronizeStart();
|
||||||
|
|
||||||
|
virtual int Process(ClientThread &client);
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Protected constructor - this is a singleton.
|
||||||
|
ClientStateSynchronizeStart();
|
||||||
|
|
||||||
|
virtual int InternalProcess(ClientThread &client, boost::shared_ptr<NetPacket> packet);
|
||||||
|
};
|
||||||
|
|
||||||
|
// State: Wait for game start.
|
||||||
|
class ClientStateWaitStart : public AbstractClientStateReceiving
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Access the state singleton.
|
||||||
|
static ClientStateWaitStart &Instance();
|
||||||
|
|
||||||
|
virtual ~ClientStateWaitStart();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Protected constructor - this is a singleton.
|
||||||
|
ClientStateWaitStart();
|
||||||
|
|
||||||
|
virtual int InternalProcess(ClientThread &client, boost::shared_ptr<NetPacket> packet);
|
||||||
|
};
|
||||||
|
|
||||||
// State: Wait for start of the next hand.
|
// State: Wait for start of the next hand.
|
||||||
class ClientStateWaitHand : public AbstractClientStateReceiving
|
class ClientStateWaitHand : public AbstractClientStateReceiving
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ protected:
|
|||||||
|
|
||||||
bool GetCachedPlayerInfo(unsigned id, PlayerInfo &info) const;
|
bool GetCachedPlayerInfo(unsigned id, PlayerInfo &info) const;
|
||||||
void RequestPlayerInfo(unsigned id);
|
void RequestPlayerInfo(unsigned id);
|
||||||
void SetPlayerInfo(unsigned id, const PlayerInfo &info);
|
void SetPlayerInfo(unsigned id, const PlayerInfo &info, bool retrieveAvatar = true);
|
||||||
void SetNewGameAdmin(unsigned id);
|
void SetNewGameAdmin(unsigned id);
|
||||||
|
|
||||||
void AddTempAvatarData(unsigned playerId, unsigned avatarSize, AvatarFileType type);
|
void AddTempAvatarData(unsigned playerId, unsigned avatarSize, AvatarFileType type);
|
||||||
@@ -134,6 +134,8 @@ protected:
|
|||||||
bool IsSessionEstablished() const;
|
bool IsSessionEstablished() const;
|
||||||
void SetSessionEstablished(bool flag);
|
void SetSessionEstablished(bool flag);
|
||||||
|
|
||||||
|
bool IsSynchronized() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
NetPacketList m_outPacketList;
|
NetPacketList m_outPacketList;
|
||||||
@@ -177,6 +179,8 @@ friend class ClientStateStartSession;
|
|||||||
friend class ClientStateWaitSession;
|
friend class ClientStateWaitSession;
|
||||||
friend class ClientStateWaitJoin;
|
friend class ClientStateWaitJoin;
|
||||||
friend class ClientStateWaitGame;
|
friend class ClientStateWaitGame;
|
||||||
|
friend class ClientStateSynchronizeStart;
|
||||||
|
friend class ClientStateWaitStart;
|
||||||
friend class ClientStateWaitHand;
|
friend class ClientStateWaitHand;
|
||||||
friend class ClientStateRunHand;
|
friend class ClientStateRunHand;
|
||||||
friend class ClientStateFinal;
|
friend class ClientStateFinal;
|
||||||
|
|||||||
@@ -395,16 +395,6 @@ AbstractClientStateReceiving::Process(ClientThread &client)
|
|||||||
NetPacketPlayerInfo::Data infoData;
|
NetPacketPlayerInfo::Data infoData;
|
||||||
tmpPacket->ToNetPacketPlayerInfo()->GetData(infoData);
|
tmpPacket->ToNetPacketPlayerInfo()->GetData(infoData);
|
||||||
client.SetPlayerInfo(infoData.playerId, infoData.playerInfo);
|
client.SetPlayerInfo(infoData.playerId, infoData.playerInfo);
|
||||||
// Retrieve avatar if needed.
|
|
||||||
if (infoData.playerInfo.hasAvatar && !client.GetAvatarManager().HasAvatar(infoData.playerInfo.avatar))
|
|
||||||
{
|
|
||||||
boost::shared_ptr<NetPacket> retrieveAvatar(new NetPacketRetrieveAvatar);
|
|
||||||
NetPacketRetrieveAvatar::Data retrieveAvatarData;
|
|
||||||
retrieveAvatarData.requestId = infoData.playerId;
|
|
||||||
retrieveAvatarData.avatar = infoData.playerInfo.avatar;
|
|
||||||
static_cast<NetPacketRetrieveAvatar *>(retrieveAvatar.get())->SetData(retrieveAvatarData);
|
|
||||||
client.GetSender().Send(client.GetContext().GetSocket(), retrieveAvatar);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (tmpPacket->ToNetPacketRemovedFromGame())
|
else if (tmpPacket->ToNetPacketRemovedFromGame())
|
||||||
{
|
{
|
||||||
@@ -651,33 +641,9 @@ ClientStateWaitGame::InternalProcess(ClientThread &client, boost::shared_ptr<Net
|
|||||||
{
|
{
|
||||||
int retVal = MSG_SOCK_INTERNAL_PENDING;
|
int retVal = MSG_SOCK_INTERNAL_PENDING;
|
||||||
|
|
||||||
if (packet->ToNetPacketGameStart())
|
if (packet->ToNetPacketStartEvent())
|
||||||
{
|
{
|
||||||
// Start the network game as client.
|
client.SetState(ClientStateSynchronizeStart::Instance());
|
||||||
NetPacketGameStart::Data gameStartData;
|
|
||||||
packet->ToNetPacketGameStart()->GetData(gameStartData);
|
|
||||||
|
|
||||||
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());
|
|
||||||
retVal = MSG_NET_GAME_CLIENT_START;
|
|
||||||
}
|
}
|
||||||
else if (packet->ToNetPacketPlayerJoined())
|
else if (packet->ToNetPacketPlayerJoined())
|
||||||
{
|
{
|
||||||
@@ -719,6 +685,103 @@ ClientStateWaitGame::InternalProcess(ClientThread &client, boost::shared_ptr<Net
|
|||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ClientStateSynchronizeStart &
|
||||||
|
ClientStateSynchronizeStart::Instance()
|
||||||
|
{
|
||||||
|
static ClientStateSynchronizeStart state;
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientStateSynchronizeStart::ClientStateSynchronizeStart()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientStateSynchronizeStart::~ClientStateSynchronizeStart()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ClientStateSynchronizeStart::Process(ClientThread &client)
|
||||||
|
{
|
||||||
|
int retVal = AbstractClientStateReceiving::Process(client);
|
||||||
|
|
||||||
|
if (client.IsSynchronized())
|
||||||
|
{
|
||||||
|
boost::shared_ptr<NetPacket> startAck(new NetPacketStartEventAck);
|
||||||
|
client.GetSender().Send(client.GetContext().GetSocket(), startAck);
|
||||||
|
client.SetState(ClientStateWaitStart::Instance());
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ClientStateSynchronizeStart::InternalProcess(ClientThread &client, boost::shared_ptr<NetPacket> packet)
|
||||||
|
{
|
||||||
|
int retVal = MSG_SOCK_INTERNAL_PENDING;
|
||||||
|
|
||||||
|
if (packet->ToNetPacketGameStart())
|
||||||
|
throw ClientException(ERR_NET_START_TIMEOUT, 0);
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ClientStateWaitStart &
|
||||||
|
ClientStateWaitStart::Instance()
|
||||||
|
{
|
||||||
|
static ClientStateWaitStart state;
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientStateWaitStart::ClientStateWaitStart()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientStateWaitStart::~ClientStateWaitStart()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ClientStateWaitStart::InternalProcess(ClientThread &client, boost::shared_ptr<NetPacket> packet)
|
||||||
|
{
|
||||||
|
int retVal = MSG_SOCK_INTERNAL_PENDING;
|
||||||
|
|
||||||
|
if (packet->ToNetPacketGameStart())
|
||||||
|
{
|
||||||
|
// Start the network game as client.
|
||||||
|
NetPacketGameStart::Data gameStartData;
|
||||||
|
packet->ToNetPacketGameStart()->GetData(gameStartData);
|
||||||
|
|
||||||
|
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());
|
||||||
|
retVal = MSG_NET_GAME_CLIENT_START;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
ClientStateWaitHand &
|
ClientStateWaitHand &
|
||||||
ClientStateWaitHand::Instance()
|
ClientStateWaitHand::Instance()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -381,7 +381,7 @@ ClientThread::RequestPlayerInfo(unsigned id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ClientThread::SetPlayerInfo(unsigned id, const PlayerInfo &info)
|
ClientThread::SetPlayerInfo(unsigned id, const PlayerInfo &info, bool retrieveAvatar)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(m_playerInfoMapMutex);
|
boost::mutex::scoped_lock lock(m_playerInfoMapMutex);
|
||||||
@@ -404,6 +404,23 @@ ClientThread::SetPlayerInfo(unsigned id, const PlayerInfo &info)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Retrieve avatar if needed.
|
||||||
|
if (retrieveAvatar && info.hasAvatar && !GetAvatarManager().HasAvatar(info.avatar))
|
||||||
|
{
|
||||||
|
boost::shared_ptr<NetPacket> retrieveAvatar(new NetPacketRetrieveAvatar);
|
||||||
|
NetPacketRetrieveAvatar::Data retrieveAvatarData;
|
||||||
|
retrieveAvatarData.requestId = id;
|
||||||
|
retrieveAvatarData.avatar = info.avatar;
|
||||||
|
static_cast<NetPacketRetrieveAvatar *>(retrieveAvatar.get())->SetData(retrieveAvatarData);
|
||||||
|
GetSender().Send(GetContext().GetSocket(), retrieveAvatar);
|
||||||
|
|
||||||
|
// Insert empty value in list to synchronize waiting.
|
||||||
|
m_tempAvatarMap[id] = boost::shared_ptr<AvatarData>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove from request list.
|
||||||
|
m_playerInfoRequestList.remove(id);
|
||||||
|
|
||||||
// Notify GUI
|
// Notify GUI
|
||||||
GetCallback().SignalNetClientPlayerChanged(id, info.playerName);
|
GetCallback().SignalNetClientPlayerChanged(id, info.playerName);
|
||||||
|
|
||||||
@@ -464,7 +481,7 @@ ClientThread::CompleteTempAvatarData(unsigned playerId)
|
|||||||
m_tempAvatarMap.erase(pos);
|
m_tempAvatarMap.erase(pos);
|
||||||
|
|
||||||
// Update player info, but never re-request avatar.
|
// Update player info, but never re-request avatar.
|
||||||
SetPlayerInfo(playerId, tmpPlayerInfo);
|
SetPlayerInfo(playerId, tmpPlayerInfo, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ClientContext &
|
const ClientContext &
|
||||||
@@ -822,3 +839,9 @@ ClientThread::SetSessionEstablished(bool flag)
|
|||||||
m_sessionEstablished = flag;
|
m_sessionEstablished = flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ClientThread::IsSynchronized() const
|
||||||
|
{
|
||||||
|
return (m_playerInfoRequestList.empty() && m_tempAvatarMap.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ using namespace std;
|
|||||||
#define NET_TYPE_KICK_PLAYER 0x0040
|
#define NET_TYPE_KICK_PLAYER 0x0040
|
||||||
#define NET_TYPE_LEAVE_CURRENT_GAME 0x0041
|
#define NET_TYPE_LEAVE_CURRENT_GAME 0x0041
|
||||||
#define NET_TYPE_START_EVENT 0x0042
|
#define NET_TYPE_START_EVENT 0x0042
|
||||||
|
#define NET_TYPE_START_EVENT_ACK 0x0043
|
||||||
#define NET_TYPE_GAME_START 0x0050
|
#define NET_TYPE_GAME_START 0x0050
|
||||||
#define NET_TYPE_HAND_START 0x0051
|
#define NET_TYPE_HAND_START 0x0051
|
||||||
#define NET_TYPE_PLAYERS_TURN 0x0052
|
#define NET_TYPE_PLAYERS_TURN 0x0052
|
||||||
@@ -297,6 +298,12 @@ struct GCC_PACKED NetPacketStartEventData
|
|||||||
u_int16_t reserved;
|
u_int16_t reserved;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct GCC_PACKED NetPacketStartEventAckData
|
||||||
|
{
|
||||||
|
NetPacketHeader head;
|
||||||
|
u_int32_t reserved;
|
||||||
|
};
|
||||||
|
|
||||||
struct GCC_PACKED NetPacketGameStartData
|
struct GCC_PACKED NetPacketGameStartData
|
||||||
{
|
{
|
||||||
NetPacketHeader head;
|
NetPacketHeader head;
|
||||||
@@ -646,6 +653,9 @@ NetPacket::Create(char *data, unsigned &dataSize)
|
|||||||
case NET_TYPE_START_EVENT:
|
case NET_TYPE_START_EVENT:
|
||||||
tmpPacket = boost::shared_ptr<NetPacket>(new NetPacketStartEvent);
|
tmpPacket = boost::shared_ptr<NetPacket>(new NetPacketStartEvent);
|
||||||
break;
|
break;
|
||||||
|
case NET_TYPE_START_EVENT_ACK:
|
||||||
|
tmpPacket = boost::shared_ptr<NetPacket>(new NetPacketStartEventAck);
|
||||||
|
break;
|
||||||
case NET_TYPE_GAME_START:
|
case NET_TYPE_GAME_START:
|
||||||
tmpPacket = boost::shared_ptr<NetPacket>(new NetPacketGameStart);
|
tmpPacket = boost::shared_ptr<NetPacket>(new NetPacketGameStart);
|
||||||
break;
|
break;
|
||||||
@@ -913,6 +923,12 @@ NetPacket::ToNetPacketStartEvent() const
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const NetPacketStartEventAck *
|
||||||
|
NetPacket::ToNetPacketStartEventAck() const
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
const NetPacketGameStart *
|
const NetPacketGameStart *
|
||||||
NetPacket::ToNetPacketGameStart() const
|
NetPacket::ToNetPacketGameStart() const
|
||||||
{
|
{
|
||||||
@@ -2641,7 +2657,7 @@ NetPacketKickPlayer::InternalCheck(const NetPacketHeader*) const
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
NetPacketLeaveCurrentGame::NetPacketLeaveCurrentGame()
|
NetPacketLeaveCurrentGame::NetPacketLeaveCurrentGame()
|
||||||
: NetPacket(NET_TYPE_LEAVE_CURRENT_GAME, sizeof(NetPacketLeaveCurrentGame), sizeof(NetPacketLeaveCurrentGame))
|
: NetPacket(NET_TYPE_LEAVE_CURRENT_GAME, sizeof(NetPacketLeaveCurrentGameData), sizeof(NetPacketLeaveCurrentGameData))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2735,6 +2751,43 @@ NetPacketStartEvent::InternalCheck(const NetPacketHeader*) const
|
|||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
NetPacketStartEventAck::NetPacketStartEventAck()
|
||||||
|
: NetPacket(NET_TYPE_START_EVENT_ACK, sizeof(NetPacketStartEventAckData), sizeof(NetPacketStartEventAckData))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NetPacketStartEventAck::~NetPacketStartEventAck()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::shared_ptr<NetPacket>
|
||||||
|
NetPacketStartEventAck::Clone() const
|
||||||
|
{
|
||||||
|
boost::shared_ptr<NetPacket> newPacket(new NetPacketStartEventAck);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
newPacket->SetRawData(GetRawData());
|
||||||
|
} catch (const NetException &)
|
||||||
|
{
|
||||||
|
// Need to return the new packet anyway.
|
||||||
|
}
|
||||||
|
return newPacket;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NetPacketStartEventAck *
|
||||||
|
NetPacketStartEventAck::ToNetPacketStartEventAck() const
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NetPacketStartEventAck::InternalCheck(const NetPacketHeader*) const
|
||||||
|
{
|
||||||
|
// Nothing to do.
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
NetPacketGameStart::NetPacketGameStart()
|
NetPacketGameStart::NetPacketGameStart()
|
||||||
: NetPacket(NET_TYPE_GAME_START, sizeof(NetPacketGameStartData), MAX_PACKET_SIZE)
|
: NetPacket(NET_TYPE_GAME_START, sizeof(NetPacketGameStartData), MAX_PACKET_SIZE)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ using namespace std;
|
|||||||
#define SERVER_SHOW_CARDS_DELAY_SEC 2
|
#define SERVER_SHOW_CARDS_DELAY_SEC 2
|
||||||
#define SERVER_PLAYER_TIMEOUT_ADD_DELAY_SEC 2
|
#define SERVER_PLAYER_TIMEOUT_ADD_DELAY_SEC 2
|
||||||
#define SERVER_COMPUTER_ACTION_DELAY_SEC 2
|
#define SERVER_COMPUTER_ACTION_DELAY_SEC 2
|
||||||
|
#define SERVER_START_GAME_TIMEOUT_SEC 10
|
||||||
|
|
||||||
#define SERVER_COMPUTER_PLAYER_NAME "Computer"
|
#define SERVER_COMPUTER_PLAYER_NAME "Computer"
|
||||||
|
|
||||||
@@ -286,35 +287,41 @@ ServerGameStateInit::HandleNewSession(ServerGameThread &server, SessionWrapper s
|
|||||||
int
|
int
|
||||||
ServerGameStateInit::InternalProcess(ServerGameThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet)
|
ServerGameStateInit::InternalProcess(ServerGameThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet)
|
||||||
{
|
{
|
||||||
int retVal = MSG_SOCK_INIT_DONE;
|
int retVal = MSG_SOCK_INTERNAL_PENDING;
|
||||||
|
|
||||||
if (packet->ToNetPacketStartEvent())
|
if (packet->ToNetPacketStartEvent())
|
||||||
{
|
{
|
||||||
NetPacketStartEvent::Data startData;
|
// Only admins are allowed to start the game.
|
||||||
packet->ToNetPacketStartEvent()->GetData(startData);
|
if (session.playerData->GetRights() == PLAYER_RIGHTS_ADMIN)
|
||||||
|
|
||||||
server.ResetComputerPlayerList();
|
|
||||||
|
|
||||||
if (startData.fillUpWithCpuPlayers)
|
|
||||||
{
|
{
|
||||||
int remainingSlots = server.GetGameData().maxNumberOfPlayers - server.GetCurNumberOfPlayers();
|
NetPacketStartEvent::Data startData;
|
||||||
for (int i = 1; i <= remainingSlots; i++)
|
packet->ToNetPacketStartEvent()->GetData(startData);
|
||||||
|
|
||||||
|
// Fill up with computer players.
|
||||||
|
server.ResetComputerPlayerList();
|
||||||
|
|
||||||
|
if (startData.fillUpWithCpuPlayers)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<PlayerData> tmpPlayerData(
|
int remainingSlots = server.GetGameData().maxNumberOfPlayers - server.GetCurNumberOfPlayers();
|
||||||
new PlayerData(server.GetLobbyThread().GetNextUniquePlayerId(), 0, PLAYER_TYPE_COMPUTER, PLAYER_RIGHTS_NORMAL));
|
for (int i = 1; i <= remainingSlots; i++)
|
||||||
|
{
|
||||||
|
boost::shared_ptr<PlayerData> tmpPlayerData(
|
||||||
|
new PlayerData(server.GetLobbyThread().GetNextUniquePlayerId(), 0, PLAYER_TYPE_COMPUTER, PLAYER_RIGHTS_NORMAL));
|
||||||
|
|
||||||
ostringstream name;
|
ostringstream name;
|
||||||
name << SERVER_COMPUTER_PLAYER_NAME << i;
|
name << SERVER_COMPUTER_PLAYER_NAME << i;
|
||||||
tmpPlayerData->SetName(name.str());
|
tmpPlayerData->SetName(name.str());
|
||||||
server.AddComputerPlayer(tmpPlayerData);
|
server.AddComputerPlayer(tmpPlayerData);
|
||||||
|
|
||||||
// Send "Player Joined" to other fully connected clients.
|
// Send "Player Joined" to other fully connected clients.
|
||||||
server.SendToAllPlayers(CreateNetPacketPlayerJoined(*tmpPlayerData), SessionData::Game);
|
server.SendToAllPlayers(CreateNetPacketPlayerJoined(*tmpPlayerData), SessionData::Game);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
// Wait for all players to confirm start of game.
|
||||||
|
server.SendToAllPlayers(boost::shared_ptr<NetPacket>(packet->Clone()), SessionData::Game);
|
||||||
|
|
||||||
server.InternalStartGame();
|
server.SetState(ServerGameStateWaitAck::Instance());
|
||||||
server.SetState(SERVER_START_GAME_STATE::Instance());
|
}
|
||||||
}
|
}
|
||||||
else if (packet->ToNetPacketKickPlayer())
|
else if (packet->ToNetPacketKickPlayer())
|
||||||
{
|
{
|
||||||
@@ -365,6 +372,64 @@ AbstractServerGameStateRunning::HandleNewSession(ServerGameThread &server, Sessi
|
|||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
boost::thread_specific_ptr<ServerGameStateWaitAck> ServerGameStateWaitAck::Ptr;
|
||||||
|
|
||||||
|
ServerGameStateWaitAck &
|
||||||
|
ServerGameStateWaitAck::Instance()
|
||||||
|
{
|
||||||
|
if (!Ptr.get())
|
||||||
|
Ptr.reset(new ServerGameStateWaitAck);
|
||||||
|
|
||||||
|
return *Ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerGameStateWaitAck::ServerGameStateWaitAck()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerGameStateWaitAck::~ServerGameStateWaitAck()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ServerGameStateWaitAck::Process(ServerGameThread &server)
|
||||||
|
{
|
||||||
|
int retVal;
|
||||||
|
|
||||||
|
if (GetTimer().elapsed().total_seconds() >= SERVER_START_GAME_TIMEOUT_SEC)
|
||||||
|
{
|
||||||
|
// On timeout: start anyway.
|
||||||
|
server.SetState(SERVER_START_GAME_STATE::Instance());
|
||||||
|
retVal = MSG_SOCK_INIT_DONE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
retVal = AbstractServerGameStateReceiving::Process(server);
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ServerGameStateWaitAck::InternalProcess(ServerGameThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet)
|
||||||
|
{
|
||||||
|
int retVal = MSG_SOCK_INTERNAL_PENDING;
|
||||||
|
|
||||||
|
if (packet->ToNetPacketStartEventAck())
|
||||||
|
{
|
||||||
|
session.sessionData->SetReadyFlag();
|
||||||
|
if (server.GetSessionManager().CountReadySessions() == server.GetSessionManager().GetRawSessionCount())
|
||||||
|
{
|
||||||
|
// Everyone is ready.
|
||||||
|
server.SetState(SERVER_START_GAME_STATE::Instance());
|
||||||
|
retVal = MSG_SOCK_INIT_DONE;
|
||||||
|
}
|
||||||
|
retVal = MSG_SOCK_INIT_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
boost::thread_specific_ptr<ServerGameStateStartGame> ServerGameStateStartGame::Ptr;
|
boost::thread_specific_ptr<ServerGameStateStartGame> ServerGameStateStartGame::Ptr;
|
||||||
|
|
||||||
ServerGameStateStartGame &
|
ServerGameStateStartGame &
|
||||||
@@ -387,6 +452,8 @@ ServerGameStateStartGame::~ServerGameStateStartGame()
|
|||||||
int
|
int
|
||||||
ServerGameStateStartGame::Process(ServerGameThread &server)
|
ServerGameStateStartGame::Process(ServerGameThread &server)
|
||||||
{
|
{
|
||||||
|
server.InternalStartGame();
|
||||||
|
|
||||||
boost::shared_ptr<NetPacket> answer(new NetPacketGameStart);
|
boost::shared_ptr<NetPacket> answer(new NetPacketGameStart);
|
||||||
|
|
||||||
NetPacketGameStart::Data gameStartData;
|
NetPacketGameStart::Data gameStartData;
|
||||||
|
|||||||
@@ -152,6 +152,7 @@ ServerGameThread::Main()
|
|||||||
GetSender().SignalTermination();
|
GetSender().SignalTermination();
|
||||||
GetSender().Join(SENDER_THREAD_TERMINATE_TIMEOUT);
|
GetSender().Join(SENDER_THREAD_TERMINATE_TIMEOUT);
|
||||||
|
|
||||||
|
ResetComputerPlayerList();
|
||||||
GetLobbyThread().RemoveGame(GetId());
|
GetLobbyThread().RemoveGame(GetId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,14 +274,27 @@ ServerGameThread::IsRunning() const
|
|||||||
void
|
void
|
||||||
ServerGameThread::AddComputerPlayer(boost::shared_ptr<PlayerData> player)
|
ServerGameThread::AddComputerPlayer(boost::shared_ptr<PlayerData> player)
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(m_computerPlayerListMutex);
|
{
|
||||||
m_computerPlayerList.push_back(player);
|
boost::mutex::scoped_lock lock(m_computerPlayerListMutex);
|
||||||
|
m_computerPlayerList.push_back(player);
|
||||||
|
}
|
||||||
|
GetLobbyThread().AddComputerPlayer(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ServerGameThread::ResetComputerPlayerList()
|
ServerGameThread::ResetComputerPlayerList()
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(m_computerPlayerListMutex);
|
boost::mutex::scoped_lock lock(m_computerPlayerListMutex);
|
||||||
|
|
||||||
|
PlayerDataList::iterator i = m_computerPlayerList.begin();
|
||||||
|
PlayerDataList::iterator end = m_computerPlayerList.end();
|
||||||
|
|
||||||
|
while (i != end)
|
||||||
|
{
|
||||||
|
GetLobbyThread().RemoveComputerPlayer(*i);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
m_computerPlayerList.clear();
|
m_computerPlayerList.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -176,6 +176,20 @@ ServerLobbyThread::HandleGameRetrieveAvatar(SessionWrapper session, const NetPac
|
|||||||
HandleNetPacketRetrieveAvatar(session, tmpPacket);
|
HandleNetPacketRetrieveAvatar(session, tmpPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ServerLobbyThread::AddComputerPlayer(boost::shared_ptr<PlayerData> player)
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock lock(m_computerPlayersMutex);
|
||||||
|
m_computerPlayers.insert(PlayerDataMap::value_type(player->GetUniqueId(), player));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ServerLobbyThread::RemoveComputerPlayer(boost::shared_ptr<PlayerData> player)
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock lock(m_computerPlayersMutex);
|
||||||
|
m_computerPlayers.erase(player->GetUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ServerLobbyThread::RemoveGame(unsigned id)
|
ServerLobbyThread::RemoveGame(unsigned id)
|
||||||
{
|
{
|
||||||
@@ -446,6 +460,13 @@ ServerLobbyThread::HandleNetPacketRetrievePlayerInfo(SessionWrapper session, con
|
|||||||
boost::shared_ptr<PlayerData> tmpPlayer = m_sessionManager.GetSessionByUniquePlayerId(request.playerId).playerData;
|
boost::shared_ptr<PlayerData> tmpPlayer = m_sessionManager.GetSessionByUniquePlayerId(request.playerId).playerData;
|
||||||
if (!tmpPlayer.get())
|
if (!tmpPlayer.get())
|
||||||
tmpPlayer = m_gameSessionManager.GetSessionByUniquePlayerId(request.playerId).playerData;
|
tmpPlayer = m_gameSessionManager.GetSessionByUniquePlayerId(request.playerId).playerData;
|
||||||
|
if (!tmpPlayer.get())
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock lock(m_computerPlayersMutex);
|
||||||
|
PlayerDataMap::const_iterator pos = m_computerPlayers.find(request.playerId);
|
||||||
|
if (pos != m_computerPlayers.end())
|
||||||
|
tmpPlayer = pos->second;
|
||||||
|
}
|
||||||
|
|
||||||
if (tmpPlayer.get())
|
if (tmpPlayer.get())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
#include <net/sessiondata.h>
|
#include <net/sessiondata.h>
|
||||||
|
|
||||||
SessionData::SessionData(SOCKET sockfd, unsigned id)
|
SessionData::SessionData(SOCKET sockfd, unsigned id)
|
||||||
: m_sockfd(sockfd), m_id(id), m_state(SessionData::Init)
|
: m_sockfd(sockfd), m_id(id), m_state(SessionData::Init), m_readyFlag(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,6 +58,27 @@ SessionData::GetSocket() const
|
|||||||
return m_sockfd;
|
return m_sockfd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SessionData::SetReadyFlag()
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock lock(m_dataMutex);
|
||||||
|
m_readyFlag = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SessionData::ResetReadyFlag()
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock lock(m_dataMutex);
|
||||||
|
m_readyFlag = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
SessionData::IsReady() const
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock lock(m_dataMutex);
|
||||||
|
return m_readyFlag;
|
||||||
|
}
|
||||||
|
|
||||||
const std::string &
|
const std::string &
|
||||||
SessionData::GetClientAddr() const
|
SessionData::GetClientAddr() const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -292,6 +292,24 @@ SessionManager::ForEach(boost::function<void (SessionWrapper)> func)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
SessionManager::CountReadySessions() const
|
||||||
|
{
|
||||||
|
unsigned counter = 0;
|
||||||
|
boost::mutex::scoped_lock lock(m_sessionMapMutex);
|
||||||
|
|
||||||
|
SessionMap::const_iterator i = m_sessionMap.begin();
|
||||||
|
SessionMap::const_iterator end = m_sessionMap.end();
|
||||||
|
|
||||||
|
while (i != end)
|
||||||
|
{
|
||||||
|
if ((*i).second.sessionData->IsReady())
|
||||||
|
++counter;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SessionManager::Clear()
|
SessionManager::Clear()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ class NetPacketGameAdminChanged;
|
|||||||
class NetPacketKickPlayer;
|
class NetPacketKickPlayer;
|
||||||
class NetPacketLeaveCurrentGame;
|
class NetPacketLeaveCurrentGame;
|
||||||
class NetPacketStartEvent;
|
class NetPacketStartEvent;
|
||||||
|
class NetPacketStartEventAck;
|
||||||
class NetPacketGameStart;
|
class NetPacketGameStart;
|
||||||
class NetPacketHandStart;
|
class NetPacketHandStart;
|
||||||
class NetPacketPlayersTurn;
|
class NetPacketPlayersTurn;
|
||||||
@@ -125,6 +126,7 @@ public:
|
|||||||
virtual const NetPacketKickPlayer *ToNetPacketKickPlayer() const;
|
virtual const NetPacketKickPlayer *ToNetPacketKickPlayer() const;
|
||||||
virtual const NetPacketLeaveCurrentGame *ToNetPacketLeaveCurrentGame() const;
|
virtual const NetPacketLeaveCurrentGame *ToNetPacketLeaveCurrentGame() const;
|
||||||
virtual const NetPacketStartEvent *ToNetPacketStartEvent() const;
|
virtual const NetPacketStartEvent *ToNetPacketStartEvent() const;
|
||||||
|
virtual const NetPacketStartEventAck *ToNetPacketStartEventAck() const;
|
||||||
virtual const NetPacketGameStart *ToNetPacketGameStart() const;
|
virtual const NetPacketGameStart *ToNetPacketGameStart() const;
|
||||||
virtual const NetPacketHandStart *ToNetPacketHandStart() const;
|
virtual const NetPacketHandStart *ToNetPacketHandStart() const;
|
||||||
virtual const NetPacketPlayersTurn *ToNetPacketPlayersTurn() const;
|
virtual const NetPacketPlayersTurn *ToNetPacketPlayersTurn() const;
|
||||||
@@ -681,6 +683,22 @@ protected:
|
|||||||
virtual void InternalCheck(const NetPacketHeader* data) const;
|
virtual void InternalCheck(const NetPacketHeader* data) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class NetPacketStartEventAck : public NetPacket
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
NetPacketStartEventAck();
|
||||||
|
virtual ~NetPacketStartEventAck();
|
||||||
|
|
||||||
|
virtual boost::shared_ptr<NetPacket> Clone() const;
|
||||||
|
|
||||||
|
virtual const NetPacketStartEventAck *ToNetPacketStartEventAck() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual void InternalCheck(const NetPacketHeader* data) const;
|
||||||
|
};
|
||||||
|
|
||||||
class NetPacketGameStart : public NetPacket
|
class NetPacketGameStart : public NetPacket
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -129,6 +129,30 @@ private:
|
|||||||
static boost::thread_specific_ptr<ServerGameStateInit> Ptr;
|
static boost::thread_specific_ptr<ServerGameStateInit> Ptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Wait for Ack of start event.
|
||||||
|
class ServerGameStateWaitAck : public AbstractServerGameStateReceiving, public AbstractServerGameStateRunning, public AbstractServerGameStateTimer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Access the state singleton.
|
||||||
|
static ServerGameStateWaitAck &Instance();
|
||||||
|
|
||||||
|
virtual ~ServerGameStateWaitAck();
|
||||||
|
|
||||||
|
// Timeout if waiting takes too long.
|
||||||
|
virtual int Process(ServerGameThread &server);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Protected constructor - this is a singleton.
|
||||||
|
ServerGameStateWaitAck();
|
||||||
|
|
||||||
|
virtual int InternalProcess(ServerGameThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
static boost::thread_specific_ptr<ServerGameStateWaitAck> Ptr;
|
||||||
|
};
|
||||||
|
|
||||||
// State: Start server game.
|
// State: Start server game.
|
||||||
class ServerGameStateStartGame : public AbstractServerGameStateRunning
|
class ServerGameStateStartGame : public AbstractServerGameStateRunning
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -143,6 +143,7 @@ private:
|
|||||||
friend class AbstractServerGameStateReceiving;
|
friend class AbstractServerGameStateReceiving;
|
||||||
friend class AbstractServerGameStateRunning;
|
friend class AbstractServerGameStateRunning;
|
||||||
friend class ServerGameStateInit;
|
friend class ServerGameStateInit;
|
||||||
|
friend class ServerGameStateWaitAck;
|
||||||
friend class ServerGameStateStartGame;
|
friend class ServerGameStateStartGame;
|
||||||
friend class ServerGameStateStartHand;
|
friend class ServerGameStateStartHand;
|
||||||
friend class ServerGameStateStartRound;
|
friend class ServerGameStateStartRound;
|
||||||
|
|||||||
@@ -63,6 +63,9 @@ public:
|
|||||||
void HandleGameRetrievePlayerInfo(SessionWrapper session, const NetPacketRetrievePlayerInfo &tmpPacket);
|
void HandleGameRetrievePlayerInfo(SessionWrapper session, const NetPacketRetrievePlayerInfo &tmpPacket);
|
||||||
void HandleGameRetrieveAvatar(SessionWrapper session, const NetPacketRetrieveAvatar &tmpPacket);
|
void HandleGameRetrieveAvatar(SessionWrapper session, const NetPacketRetrieveAvatar &tmpPacket);
|
||||||
|
|
||||||
|
void AddComputerPlayer(boost::shared_ptr<PlayerData> player);
|
||||||
|
void RemoveComputerPlayer(boost::shared_ptr<PlayerData> player);
|
||||||
|
|
||||||
void RemoveGame(unsigned id);
|
void RemoveGame(unsigned id);
|
||||||
|
|
||||||
u_int32_t GetNextUniquePlayerId();
|
u_int32_t GetNextUniquePlayerId();
|
||||||
@@ -145,6 +148,9 @@ private:
|
|||||||
RemoveGameList m_removeGameList;
|
RemoveGameList m_removeGameList;
|
||||||
mutable boost::mutex m_removeGameListMutex;
|
mutable boost::mutex m_removeGameListMutex;
|
||||||
|
|
||||||
|
PlayerDataMap m_computerPlayers;
|
||||||
|
mutable boost::mutex m_computerPlayersMutex;
|
||||||
|
|
||||||
GameMap m_gameMap;
|
GameMap m_gameMap;
|
||||||
|
|
||||||
std::auto_ptr<ReceiverHelper> m_receiver;
|
std::auto_ptr<ReceiverHelper> m_receiver;
|
||||||
|
|||||||
@@ -42,6 +42,10 @@ public:
|
|||||||
|
|
||||||
SOCKET GetSocket() const;
|
SOCKET GetSocket() const;
|
||||||
|
|
||||||
|
void SetReadyFlag();
|
||||||
|
void ResetReadyFlag();
|
||||||
|
bool IsReady() const;
|
||||||
|
|
||||||
const std::string &GetClientAddr() const;
|
const std::string &GetClientAddr() const;
|
||||||
void SetClientAddr(const std::string &addr);
|
void SetClientAddr(const std::string &addr);
|
||||||
|
|
||||||
@@ -53,6 +57,7 @@ private:
|
|||||||
State m_state;
|
State m_state;
|
||||||
std::string m_clientAddr;
|
std::string m_clientAddr;
|
||||||
ReceiveBuffer m_receiveBuffer;
|
ReceiveBuffer m_receiveBuffer;
|
||||||
|
bool m_readyFlag;
|
||||||
|
|
||||||
mutable boost::mutex m_dataMutex;
|
mutable boost::mutex m_dataMutex;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ public:
|
|||||||
bool IsPlayerConnected(unsigned uniqueId) const;
|
bool IsPlayerConnected(unsigned uniqueId) const;
|
||||||
|
|
||||||
void ForEach(boost::function<void (SessionWrapper)> func);
|
void ForEach(boost::function<void (SessionWrapper)> func);
|
||||||
|
unsigned CountReadySessions() const;
|
||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
unsigned GetRawSessionCount();
|
unsigned GetRawSessionCount();
|
||||||
|
|||||||
@@ -61,6 +61,7 @@
|
|||||||
#define ERR_NET_BUF_INVALID_SIZE 117
|
#define ERR_NET_BUF_INVALID_SIZE 117
|
||||||
#define ERR_NET_INVALID_REQUEST_ID 118
|
#define ERR_NET_INVALID_REQUEST_ID 118
|
||||||
#define ERR_NET_WRONG_AVATAR_SIZE 119
|
#define ERR_NET_WRONG_AVATAR_SIZE 119
|
||||||
|
#define ERR_NET_START_TIMEOUT 120
|
||||||
|
|
||||||
#define ERR_IRC_INTERNAL 151
|
#define ERR_IRC_INTERNAL 151
|
||||||
#define ERR_IRC_CONNECT_FAILED 152
|
#define ERR_IRC_CONNECT_FAILED 152
|
||||||
|
|||||||
Reference in New Issue
Block a user