Major redesign: Using game ids and player ids in gui (associated with tree view items).

Player list of all network games is now dynamically updated in lobby (no polling, server sends events).
This commit is contained in:
lotodore
2007-09-02 16:36:52 +00:00
parent 1b8616d079
commit bd53403752
23 changed files with 421 additions and 238 deletions
+8 -6
View File
@@ -36,14 +36,16 @@ public:
virtual void SignalNetClientGameInfo(int actionID) = 0;
virtual void SignalNetClientError(int errorID, int osErrorID) = 0;
virtual void SignalNetClientGameListNew(const std::string &gameName) = 0;
virtual void SignalNetClientGameListRemove(const std::string &gameName) = 0;
virtual void SignalNetClientGameListNew(unsigned gameId, const std::string &gameName) = 0;
virtual void SignalNetClientGameListRemove(unsigned gameId, const std::string &gameName) = 0;
virtual void SignalNetClientGameListPlayerJoined(unsigned gameId, unsigned playerId) = 0;
virtual void SignalNetClientGameListPlayerLeft(unsigned gameId, unsigned playerId) = 0;
virtual void SignalNetClientGameStart(boost::shared_ptr<Game> game) = 0;
virtual void SignalNetClientSelfJoined(const std::string &playerName, PlayerRights rights) = 0;
virtual void SignalNetClientPlayerJoined(const std::string &playerName, PlayerRights rights) = 0;
virtual void SignalNetClientPlayerChanged(const std::string &oldPlayerName, const std::string &newPlayerName) = 0;
virtual void SignalNetClientPlayerLeft(const std::string &playerName) = 0;
virtual void SignalNetClientSelfJoined(unsigned playerId, const std::string &playerName, PlayerRights rights) = 0;
virtual void SignalNetClientPlayerJoined(unsigned playerId, const std::string &playerName, PlayerRights rights) = 0;
virtual void SignalNetClientPlayerChanged(unsigned playerId, const std::string &newPlayerName) = 0;
virtual void SignalNetClientPlayerLeft(unsigned playerId, const std::string &playerName) = 0;
virtual void SignalNetClientChatMsg(const std::string &playerName, const std::string &msg) = 0;
virtual void SignalNetClientWaitDialog() = 0;
+11 -5
View File
@@ -62,7 +62,8 @@ public:
void SendJoinGame(const std::string &name, const std::string &password);
void SendCreateGame(const GameData &gameData, const std::string &name, const std::string &password);
GameInfo GetGameInfo(const std::string &game) const;
GameInfo GetGameInfo(unsigned playerId) const;
PlayerInfo GetPlayerInfo(unsigned playerId) const;
ClientCallback &GetCallback();
GuiInterface &GetGui();
@@ -78,8 +79,8 @@ protected:
void AddPacket(boost::shared_ptr<NetPacket> packet);
void SendPacketLoop();
PlayerInfo GetCachedPlayerInfo(unsigned id) const;
void RequestPlayerInfo(unsigned id, const PlayerInfo &tempInfo);
bool GetCachedPlayerInfo(unsigned id, PlayerInfo &info) const;
void RequestPlayerInfo(unsigned id);
void SetPlayerInfo(unsigned id, const PlayerInfo &info);
const ClientContext &GetContext() const;
@@ -112,8 +113,10 @@ protected:
void RemoveDisconnectedPlayers();
unsigned GetGameIdByName(const std::string &name) const;
void AddGameInfo(unsigned id, const GameInfo &info);
void RemoveGameInfo(unsigned id);
void AddGameInfo(unsigned gameId, const GameInfo &info);
void RemoveGameInfo(unsigned gameId);
void ModifyGameInfoAddPlayer(unsigned gameId, unsigned playerId);
void ModifyGameInfoRemovePlayer(unsigned gameId, unsigned playerId);
bool IsSessionEstablished() const;
void SetSessionEstablished(bool flag);
@@ -139,7 +142,10 @@ private:
mutable boost::mutex m_gameInfoMapMutex;
boost::shared_ptr<Game> m_game;
PlayerInfoMap m_playerInfoMap;
mutable boost::mutex m_playerInfoMapMutex;
PlayerIdList m_playerInfoRequestList;
unsigned m_curGameId;
unsigned m_guiPlayerId;
+40 -8
View File
@@ -485,6 +485,21 @@ ClientStateWaitJoin::InternalProcess(ClientThread &client, boost::shared_ptr<Net
// A new game was created on the server.
NetPacketGameListNew::Data gameListNewData;
packet->ToNetPacketGameListNew()->GetData(gameListNewData);
// Request player info for players if needed.
PlayerIdList::const_iterator i = gameListNewData.gameInfo.players.begin();
PlayerIdList::const_iterator end = gameListNewData.gameInfo.players.end();
while (i != end)
{
PlayerInfo info;
if (!client.GetCachedPlayerInfo(*i, info))
{
// Request player info.
client.RequestPlayerInfo(*i);
}
++i;
}
client.AddGameInfo(gameListNewData.gameId, gameListNewData.gameInfo);
}
else if (packet->ToNetPacketGameListUpdate())
@@ -495,6 +510,24 @@ ClientStateWaitJoin::InternalProcess(ClientThread &client, boost::shared_ptr<Net
if (gameListUpdateData.gameMode == GAME_MODE_CLOSED)
client.RemoveGameInfo(gameListUpdateData.gameId);
}
else if (packet->ToNetPacketGameListPlayerJoined())
{
NetPacketGameListPlayerJoined::Data playerJoinedData;
packet->ToNetPacketGameListPlayerJoined()->GetData(playerJoinedData);
client.ModifyGameInfoAddPlayer(playerJoinedData.gameId, playerJoinedData.playerId);
// Request player info if needed.
PlayerInfo info;
if (!client.GetCachedPlayerInfo(playerJoinedData.playerId, info))
{
client.RequestPlayerInfo(playerJoinedData.playerId);
}
}
else if (packet->ToNetPacketGameListPlayerLeft())
{
NetPacketGameListPlayerLeft::Data playerLeftData;
packet->ToNetPacketGameListPlayerLeft()->GetData(playerLeftData);
client.ModifyGameInfoRemovePlayer(playerLeftData.gameId, playerLeftData.playerId);
}
else if (packet->ToNetPacketJoinGameAck())
{
// Successfully joined a game.
@@ -573,25 +606,24 @@ ClientStateWaitGame::InternalProcess(ClientThread &client, boost::shared_ptr<Net
packet->ToNetPacketPlayerJoined()->GetData(netPlayerData);
boost::shared_ptr<PlayerData> playerData;
try
PlayerInfo info;
if (client.GetCachedPlayerInfo(netPlayerData.playerId, info))
{
PlayerInfo info = client.GetCachedPlayerInfo(netPlayerData.playerId);
playerData.reset(
new PlayerData(netPlayerData.playerId, 0, info.ptype, netPlayerData.prights));
playerData->SetName(info.playerName);
} catch (const NetException &)
}
else
{
ostringstream name;
name << "#" << netPlayerData.playerId;
// Request player info.
PlayerInfo info;
info.playerName = name.str();
client.RequestPlayerInfo(netPlayerData.playerId, info);
client.RequestPlayerInfo(netPlayerData.playerId);
// Use temporary data until the PlayerInfo request is completed.
playerData.reset(
new PlayerData(netPlayerData.playerId, 0, info.ptype, netPlayerData.prights));
playerData->SetName(info.playerName);
new PlayerData(netPlayerData.playerId, 0, PLAYER_TYPE_HUMAN, netPlayerData.prights));
playerData->SetName(name.str());
}
client.AddPlayerData(playerData);
}
+92 -51
View File
@@ -28,6 +28,7 @@
#include <game.h>
#include <boost/lambda/lambda.hpp>
#include <sstream>
#include <cassert>
using namespace std;
@@ -217,25 +218,33 @@ ClientThread::SendCreateGame(const GameData &gameData, const std::string &name,
}
GameInfo
ClientThread::GetGameInfo(const string &game) const
ClientThread::GetGameInfo(unsigned gameId) const
{
GameInfo tmpInfo;
try
{
unsigned id = GetGameIdByName(game);
boost::mutex::scoped_lock lock(m_gameInfoMapMutex);
GameInfoMap::const_iterator pos = m_gameInfoMap.find(id);
if (pos != m_gameInfoMap.end())
{
tmpInfo = pos->second;
}
} catch (const NetException &)
boost::mutex::scoped_lock lock(m_gameInfoMapMutex);
GameInfoMap::const_iterator pos = m_gameInfoMap.find(gameId);
if (pos != m_gameInfoMap.end())
{
tmpInfo = pos->second;
}
return tmpInfo;
}
PlayerInfo
ClientThread::GetPlayerInfo(unsigned playerId) const
{
boost::mutex::scoped_lock lock(m_playerInfoMapMutex);
PlayerInfo info;
if (!GetCachedPlayerInfo(playerId, info))
{
ostringstream name;
name << "#" << playerId;
info.playerName = name.str();
}
return info;
}
ClientCallback &
ClientThread::GetCallback()
{
@@ -320,43 +329,44 @@ ClientThread::SendPacketLoop()
}
}
PlayerInfo
ClientThread::GetCachedPlayerInfo(unsigned id) const
bool
ClientThread::GetCachedPlayerInfo(unsigned id, PlayerInfo &info) const
{
bool retVal = false;
boost::mutex::scoped_lock lock(m_playerInfoMapMutex);
PlayerInfoMap::const_iterator pos = m_playerInfoMap.find(id);
if (pos == m_playerInfoMap.end())
throw NetException(ERR_NET_UNKNOWN_PLAYER_ID, 0);
return pos->second;
if (pos != m_playerInfoMap.end())
{
info = pos->second;
retVal = true;
}
return retVal;
}
void
ClientThread::RequestPlayerInfo(unsigned id, const PlayerInfo &tempInfo)
ClientThread::RequestPlayerInfo(unsigned id)
{
boost::shared_ptr<NetPacket> req(new NetPacketRetrievePlayerInfo);
NetPacketRetrievePlayerInfo::Data reqData;
reqData.playerId = id;
static_cast<NetPacketRetrievePlayerInfo *>(req.get())->SetData(reqData);
GetSender().Send(GetContext().GetSocket(), req);
if (find(m_playerInfoRequestList.begin(), m_playerInfoRequestList.end(), id) == m_playerInfoRequestList.end())
{
boost::shared_ptr<NetPacket> req(new NetPacketRetrievePlayerInfo);
NetPacketRetrievePlayerInfo::Data reqData;
reqData.playerId = id;
static_cast<NetPacketRetrievePlayerInfo *>(req.get())->SetData(reqData);
GetSender().Send(GetContext().GetSocket(), req);
m_playerInfoMap[id] = tempInfo;
m_playerInfoRequestList.push_back(id);
}
}
void
ClientThread::SetPlayerInfo(unsigned id, const PlayerInfo &info)
{
PlayerInfoMap::iterator pos = m_playerInfoMap.find(id);
// Update info cache.
if (pos != m_playerInfoMap.end())
{
GetCallback().SignalNetClientPlayerChanged(pos->second.playerName, info.playerName);
pos->second = info;
}
else
{
m_playerInfoMap.insert(PlayerInfoMap::value_type(id, info));
boost::mutex::scoped_lock lock(m_playerInfoMapMutex);
m_playerInfoMap[id] = info;
}
GetCallback().SignalNetClientPlayerChanged(id, info.playerName);
// Update player data for current game.
boost::shared_ptr<PlayerData> playerData = GetPlayerDataByUniqueId(id);
@@ -464,16 +474,16 @@ ClientThread::AddPlayerData(boost::shared_ptr<PlayerData> playerData)
{
m_playerDataList.push_back(playerData);
if (playerData->GetUniqueId() == GetGuiPlayerId())
GetCallback().SignalNetClientSelfJoined(playerData->GetName(), playerData->GetRights());
GetCallback().SignalNetClientSelfJoined(playerData->GetUniqueId(), playerData->GetName(), playerData->GetRights());
else
GetCallback().SignalNetClientPlayerJoined(playerData->GetName(), playerData->GetRights());
GetCallback().SignalNetClientPlayerJoined(playerData->GetUniqueId(), playerData->GetName(), playerData->GetRights());
}
}
void
ClientThread::RemovePlayerData(unsigned playerId)
{
string playerName;
boost::shared_ptr<PlayerData> tmpData;
PlayerDataList::iterator i = m_playerDataList.begin();
PlayerDataList::iterator end = m_playerDataList.end();
@@ -481,20 +491,17 @@ ClientThread::RemovePlayerData(unsigned playerId)
{
if ((*i)->GetUniqueId() == playerId)
{
playerName = (*i)->GetName();
tmpData = *i;
m_playerDataList.erase(i);
break;
}
++i;
}
if (!playerName.empty())
if (tmpData.get())
{
// Remove name and id string.
GetCallback().SignalNetClientPlayerLeft(playerName);
ostringstream name;
name << "#" << playerId;
GetCallback().SignalNetClientPlayerLeft(name.str());
// Remove player from gui.
GetCallback().SignalNetClientPlayerLeft(tmpData->GetUniqueId(), tmpData->GetName());
}
}
@@ -623,22 +630,22 @@ ClientThread::GetGameIdByName(const std::string &name) const
}
void
ClientThread::AddGameInfo(unsigned id, const GameInfo &info)
ClientThread::AddGameInfo(unsigned gameId, const GameInfo &info)
{
{
boost::mutex::scoped_lock lock(m_gameInfoMapMutex);
m_gameInfoMap.insert(GameInfoMap::value_type(id, info));
m_gameInfoMap.insert(GameInfoMap::value_type(gameId, info));
}
GetCallback().SignalNetClientGameListNew(info.name);
GetCallback().SignalNetClientGameListNew(gameId, info.name);
}
void
ClientThread::RemoveGameInfo(unsigned id)
ClientThread::RemoveGameInfo(unsigned gameId)
{
string name;
{
boost::mutex::scoped_lock lock(m_gameInfoMapMutex);
GameInfoMap::iterator pos = m_gameInfoMap.find(id);
GameInfoMap::iterator pos = m_gameInfoMap.find(gameId);
if (pos != m_gameInfoMap.end())
{
name = pos->second.name;
@@ -646,7 +653,41 @@ ClientThread::RemoveGameInfo(unsigned id)
}
}
if (!name.empty())
GetCallback().SignalNetClientGameListRemove(name);
GetCallback().SignalNetClientGameListRemove(gameId, name);
}
void
ClientThread::ModifyGameInfoAddPlayer(unsigned gameId, unsigned playerId)
{
bool playerAdded = false;
{
boost::mutex::scoped_lock lock(m_gameInfoMapMutex);
GameInfoMap::iterator pos = m_gameInfoMap.find(gameId);
if (pos != m_gameInfoMap.end())
{
pos->second.players.push_back(playerId);
playerAdded = true;
}
}
if (playerAdded)
GetCallback().SignalNetClientGameListPlayerJoined(gameId, playerId);
}
void
ClientThread::ModifyGameInfoRemovePlayer(unsigned gameId, unsigned playerId)
{
bool playerRemoved = false;
{
boost::mutex::scoped_lock lock(m_gameInfoMapMutex);
GameInfoMap::iterator pos = m_gameInfoMap.find(gameId);
if (pos != m_gameInfoMap.end())
{
pos->second.players.remove(playerId);
playerRemoved = true;
}
}
if (playerRemoved)
GetCallback().SignalNetClientGameListPlayerLeft(gameId, playerId);
}
bool
+1 -1
View File
@@ -1091,7 +1091,7 @@ NetPacketGameListNew::GetData(NetPacketGameListNew::Data &outData) const
// Store all available players.
for (int i = 0; i < curNumPlayers; i++)
{
outData.gameInfo.players.push_back(*tmpPlayer);
outData.gameInfo.players.push_back(ntohl(*tmpPlayer));
++tmpPlayer;
}
}
+4
View File
@@ -19,6 +19,7 @@
#include <net/servergamestate.h>
#include <net/servergamethread.h>
#include <net/serverlobbythread.h>
#include <net/receiverhelper.h>
#include <net/senderthread.h>
#include <net/netpacket.h>
@@ -279,6 +280,9 @@ ServerGameStateInit::HandleNewSession(ServerGameThread &server, SessionWrapper s
session.sessionData->SetState(SessionData::Game);
// Accept session.
server.GetSessionManager().AddSession(session);
// Notify lobby.
server.GetLobbyThread().NotifyPlayerJoinedGame(server.GetId(), session.playerData->GetUniqueId());
}
}
}
+1 -2
View File
@@ -227,11 +227,10 @@ ServerGameThread::CloseSessionDelayed(SessionWrapper session)
thisPlayerLeftData.playerId = tmpPlayerData->GetUniqueId();
static_cast<NetPacketPlayerLeft *>(thisPlayerLeft.get())->SetData(thisPlayerLeftData);
GetSessionManager().SendToAllSessions(GetSender(), thisPlayerLeft, SessionData::Game);
GetCallback().SignalNetServerPlayerLeft(tmpPlayerData->GetName());
}
GetLobbyThread().CloseSessionDelayed(session);
GetLobbyThread().NotifyPlayerLeftGame(GetId(), session.playerData->GetUniqueId());
}
void
+24
View File
@@ -93,6 +93,30 @@ ServerLobbyThread::CloseSessionDelayed(SessionWrapper session)
m_closeSessionList.push_back(closeSessionData);
}
void
ServerLobbyThread::NotifyPlayerJoinedGame(unsigned gameId, unsigned playerId)
{
// Send notification to players in lobby.
boost::shared_ptr<NetPacket> packet(new NetPacketGameListPlayerJoined);
NetPacketGameListPlayerJoined::Data packetData;
packetData.gameId = gameId;
packetData.playerId = playerId;
static_cast<NetPacketGameListPlayerJoined *>(packet.get())->SetData(packetData);
m_sessionManager.SendToAllSessions(GetSender(), packet, SessionData::Established);
}
void
ServerLobbyThread::NotifyPlayerLeftGame(unsigned gameId, unsigned playerId)
{
// Send notification to players in lobby.
boost::shared_ptr<NetPacket> packet(new NetPacketGameListPlayerLeft);
NetPacketGameListPlayerLeft::Data packetData;
packetData.gameId = gameId;
packetData.playerId = playerId;
static_cast<NetPacketGameListPlayerLeft *>(packet.get())->SetData(packetData);
m_sessionManager.SendToAllSessions(GetSender(), packet, SessionData::Established);
}
void
ServerLobbyThread::RemoveGame(unsigned id)
{
-3
View File
@@ -30,9 +30,6 @@ public:
virtual void SignalNetServerSuccess(int actionID) = 0;
virtual void SignalNetServerError(int errorID, int osErrorID) = 0;
virtual void SignalNetServerPlayerJoined(const std::string &playerName) = 0;
virtual void SignalNetServerPlayerLeft(const std::string &playerName) = 0;
};
#endif
+2
View File
@@ -52,6 +52,8 @@ public:
void AddConnection(boost::shared_ptr<ConnectData> data);
void CloseSessionDelayed(SessionWrapper session);
void NotifyPlayerJoinedGame(unsigned gameId, unsigned playerId);
void NotifyPlayerLeftGame(unsigned gameId, unsigned playerId);
void RemoveGame(unsigned id);