Server support for unsubscribing/resubscribing of lobby messages. Not yet used by the client.
This commit is contained in:
@@ -22,7 +22,7 @@
|
||||
#define _OPENSSL_WRAPPER_H_
|
||||
|
||||
#ifndef HAVE_SSIZE_T
|
||||
# define HAVE_SSIZE_T
|
||||
#define HAVE_SSIZE_T
|
||||
#include <sys/types.h>
|
||||
#ifdef _WIN32 // This is only for Windows. Supports only Win32.
|
||||
#ifndef _SSIZE_T_
|
||||
|
||||
@@ -1013,8 +1013,14 @@ ClientStateSynchronizeStart::Process(ClientThread &client)
|
||||
|
||||
if (client.IsSynchronized())
|
||||
{
|
||||
// Acknowledge start.
|
||||
boost::shared_ptr<NetPacket> startAck(new NetPacketStartEventAck);
|
||||
client.GetSender().Send(client.GetContext().GetSessionData(), startAck);
|
||||
// Unsubscribe lobby messages.
|
||||
// TODO
|
||||
//boost::shared_ptr<NetPacket> unsubscr(new NetPacketUnsubscribeGameList);
|
||||
//client.GetSender().Send(client.GetContext().GetSessionData(), unsubscr);
|
||||
|
||||
client.SetState(ClientStateWaitStart::Instance());
|
||||
}
|
||||
|
||||
|
||||
@@ -213,6 +213,18 @@ AbstractServerGameStateReceiving::Process(ServerGameThread &server)
|
||||
server.SendToAllPlayers(outChat, SessionData::Game);
|
||||
}
|
||||
}
|
||||
else if (packet->ToNetPacketUnsubscribeGameList())
|
||||
{
|
||||
// We can do this directly in this thread.
|
||||
session.sessionData->ResetWantsLobbyMsg();
|
||||
}
|
||||
else if (packet->ToNetPacketResubscribeGameList())
|
||||
{
|
||||
// This needs to be performed in the lobby thread,
|
||||
// because a new game list needs to be sent.
|
||||
if (!session.sessionData->WantsLobbyMsg())
|
||||
server.GetLobbyThread().ResubscribeLobbyMsg(session);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Packet processing in subclass.
|
||||
|
||||
@@ -159,6 +159,13 @@ ServerLobbyThread::CloseSession(SessionWrapper session)
|
||||
UpdateStatisticsNumberOfPlayers();
|
||||
}
|
||||
|
||||
void
|
||||
ServerLobbyThread::ResubscribeLobbyMsg(SessionWrapper session)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_resubscribeListMutex);
|
||||
m_resubscribeList.push_back(session.sessionData->GetId());
|
||||
}
|
||||
|
||||
void
|
||||
ServerLobbyThread::NotifyPlayerJoinedGame(unsigned gameId, unsigned playerId)
|
||||
{
|
||||
@@ -168,8 +175,8 @@ ServerLobbyThread::NotifyPlayerJoinedGame(unsigned gameId, unsigned playerId)
|
||||
packetData.gameId = gameId;
|
||||
packetData.playerId = playerId;
|
||||
static_cast<NetPacketGameListPlayerJoined *>(packet.get())->SetData(packetData);
|
||||
m_sessionManager.SendToAllSessions(GetSender(), packet, SessionData::Established);
|
||||
m_gameSessionManager.SendToAllSessions(GetSender(), packet, SessionData::Game);
|
||||
m_sessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Established);
|
||||
m_gameSessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Game);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -181,8 +188,8 @@ ServerLobbyThread::NotifyPlayerLeftGame(unsigned gameId, unsigned playerId)
|
||||
packetData.gameId = gameId;
|
||||
packetData.playerId = playerId;
|
||||
static_cast<NetPacketGameListPlayerLeft *>(packet.get())->SetData(packetData);
|
||||
m_sessionManager.SendToAllSessions(GetSender(), packet, SessionData::Established);
|
||||
m_gameSessionManager.SendToAllSessions(GetSender(), packet, SessionData::Game);
|
||||
m_sessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Established);
|
||||
m_gameSessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Game);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -194,24 +201,24 @@ ServerLobbyThread::NotifyGameAdminChanged(unsigned gameId, unsigned newAdminPlay
|
||||
packetData.gameId = gameId;
|
||||
packetData.newAdminplayerId = newAdminPlayerId;
|
||||
static_cast<NetPacketGameListAdminChanged *>(packet.get())->SetData(packetData);
|
||||
m_sessionManager.SendToAllSessions(GetSender(), packet, SessionData::Established);
|
||||
m_gameSessionManager.SendToAllSessions(GetSender(), packet, SessionData::Game);
|
||||
m_sessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Established);
|
||||
m_gameSessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Game);
|
||||
}
|
||||
|
||||
void
|
||||
ServerLobbyThread::NotifyStartingGame(unsigned gameId)
|
||||
{
|
||||
boost::shared_ptr<NetPacket> packet = CreateNetPacketGameListUpdate(gameId, GAME_MODE_STARTED);
|
||||
m_sessionManager.SendToAllSessions(GetSender(), packet, SessionData::Established);
|
||||
m_gameSessionManager.SendToAllSessions(GetSender(), packet, SessionData::Game);
|
||||
m_sessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Established);
|
||||
m_gameSessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Game);
|
||||
}
|
||||
|
||||
void
|
||||
ServerLobbyThread::NotifyReopeningGame(unsigned gameId)
|
||||
{
|
||||
boost::shared_ptr<NetPacket> packet = CreateNetPacketGameListUpdate(gameId, GAME_MODE_CREATED);
|
||||
m_sessionManager.SendToAllSessions(GetSender(), packet, SessionData::Established);
|
||||
m_gameSessionManager.SendToAllSessions(GetSender(), packet, SessionData::Game);
|
||||
m_sessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Established);
|
||||
m_gameSessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Game);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -324,6 +331,8 @@ ServerLobbyThread::Main()
|
||||
RemoveGameLoop();
|
||||
// Kick players.
|
||||
RemovePlayerLoop();
|
||||
// Resubscribe Lobby Messages if needed.
|
||||
ResubscribeLobbyMsgLoop();
|
||||
// Check session timeouts.
|
||||
CheckSessionTimeoutsLoop();
|
||||
// Update avatar limitation lock.
|
||||
@@ -402,6 +411,10 @@ ServerLobbyThread::ProcessLoop()
|
||||
HandleNetPacketRetrieveAvatar(session, *packet->ToNetPacketRetrieveAvatar());
|
||||
else if (packet->ToNetPacketResetTimeout())
|
||||
{}
|
||||
else if (packet->ToNetPacketUnsubscribeGameList())
|
||||
session.sessionData->ResetWantsLobbyMsg();
|
||||
else if (packet->ToNetPacketResubscribeGameList())
|
||||
InternalResubscribeMsg(session);
|
||||
else if (packet->ToNetPacketCreateGame())
|
||||
HandleNetPacketCreateGame(session, *packet->ToNetPacketCreateGame());
|
||||
else if (packet->ToNetPacketJoinGame())
|
||||
@@ -813,15 +826,41 @@ ServerLobbyThread::RemovePlayerLoop()
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_removePlayerListMutex);
|
||||
|
||||
RemovePlayerList::iterator i = m_removePlayerList.begin();
|
||||
RemovePlayerList::iterator end = m_removePlayerList.end();
|
||||
|
||||
while (i != end)
|
||||
if (!m_removePlayerList.empty())
|
||||
{
|
||||
InternalRemovePlayer(i->first, i->second);
|
||||
++i;
|
||||
RemovePlayerList::iterator i = m_removePlayerList.begin();
|
||||
RemovePlayerList::iterator end = m_removePlayerList.end();
|
||||
|
||||
while (i != end)
|
||||
{
|
||||
InternalRemovePlayer(i->first, i->second);
|
||||
++i;
|
||||
}
|
||||
m_removePlayerList.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ServerLobbyThread::ResubscribeLobbyMsgLoop()
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_resubscribeListMutex);
|
||||
|
||||
if (!m_resubscribeList.empty())
|
||||
{
|
||||
SessionIdList::iterator i = m_resubscribeList.begin();
|
||||
SessionIdList::iterator end = m_resubscribeList.end();
|
||||
|
||||
while (i != end)
|
||||
{
|
||||
SessionWrapper tmpSession = m_gameSessionManager.GetSessionById(*i);
|
||||
if (!tmpSession.sessionData.get())
|
||||
tmpSession = m_sessionManager.GetSessionById(*i);
|
||||
if (tmpSession.sessionData.get());
|
||||
InternalResubscribeMsg(tmpSession);
|
||||
++i;
|
||||
}
|
||||
m_resubscribeList.clear();
|
||||
}
|
||||
m_removePlayerList.clear();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -875,8 +914,8 @@ ServerLobbyThread::InternalAddGame(boost::shared_ptr<ServerGameThread> game)
|
||||
// Add game to list.
|
||||
m_gameMap.insert(GameMap::value_type(game->GetId(), game));
|
||||
// Notify all players.
|
||||
m_sessionManager.SendToAllSessions(GetSender(), CreateNetPacketGameListNew(*game), SessionData::Established);
|
||||
m_gameSessionManager.SendToAllSessions(GetSender(), CreateNetPacketGameListNew(*game), SessionData::Game);
|
||||
m_sessionManager.SendLobbyMsgToAllSessions(GetSender(), CreateNetPacketGameListNew(*game), SessionData::Established);
|
||||
m_gameSessionManager.SendLobbyMsgToAllSessions(GetSender(), CreateNetPacketGameListNew(*game), SessionData::Game);
|
||||
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_statMutex);
|
||||
@@ -906,8 +945,8 @@ ServerLobbyThread::InternalRemoveGame(boost::shared_ptr<ServerGameThread> game)
|
||||
game->RemoveAllSessions();
|
||||
// Notify all players.
|
||||
boost::shared_ptr<NetPacket> packet = CreateNetPacketGameListUpdate(game->GetId(), GAME_MODE_CLOSED);
|
||||
m_sessionManager.SendToAllSessions(GetSender(), packet, SessionData::Established);
|
||||
m_gameSessionManager.SendToAllSessions(GetSender(), packet, SessionData::Game);
|
||||
m_sessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Established);
|
||||
m_gameSessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Game);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -935,6 +974,16 @@ ServerLobbyThread::InternalRemovePlayer(unsigned playerId, unsigned errorCode)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ServerLobbyThread::InternalResubscribeMsg(SessionWrapper session)
|
||||
{
|
||||
if (!session.sessionData->WantsLobbyMsg())
|
||||
{
|
||||
session.sessionData->SetWantsLobbyMsg();
|
||||
SendGameList(session.sessionData);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ServerLobbyThread::TerminateGames()
|
||||
{
|
||||
@@ -1129,8 +1178,8 @@ ServerLobbyThread::BroadcastStatisticsUpdate(const ServerStats &stats)
|
||||
try {
|
||||
static_cast<NetPacketStatisticsChanged *>(packet.get())->SetData(statData);
|
||||
|
||||
m_sessionManager.SendToAllSessions(GetSender(), packet, SessionData::Established);
|
||||
m_gameSessionManager.SendToAllSessions(GetSender(), packet, SessionData::Game);
|
||||
m_sessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Established);
|
||||
m_gameSessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Game);
|
||||
} catch (const NetException &)
|
||||
{
|
||||
// Ignore errors for now.
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
SessionData::SessionData(SOCKET sockfd, SessionId id)
|
||||
: m_sockfd(sockfd), m_id(id), m_state(SessionData::Init), m_readyFlag(false),
|
||||
m_activityTimeoutNoticeSent(false)
|
||||
m_wantsLobbyMsg(true), m_activityTimeoutNoticeSent(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -80,6 +80,27 @@ SessionData::IsReady() const
|
||||
return m_readyFlag;
|
||||
}
|
||||
|
||||
void
|
||||
SessionData::SetWantsLobbyMsg()
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_dataMutex);
|
||||
m_wantsLobbyMsg = true;
|
||||
}
|
||||
|
||||
void
|
||||
SessionData::ResetWantsLobbyMsg()
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_dataMutex);
|
||||
m_wantsLobbyMsg = false;
|
||||
}
|
||||
|
||||
bool
|
||||
SessionData::WantsLobbyMsg() const
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_dataMutex);
|
||||
return m_wantsLobbyMsg;
|
||||
}
|
||||
|
||||
const std::string &
|
||||
SessionData::GetClientAddr() const
|
||||
{
|
||||
|
||||
@@ -150,6 +150,17 @@ SessionManager::Select(unsigned timeoutMsec)
|
||||
return retSession;
|
||||
}
|
||||
|
||||
SessionWrapper
|
||||
SessionManager::GetSessionById(SessionId id) const
|
||||
{
|
||||
SessionWrapper tmpSession;
|
||||
boost::recursive_mutex::scoped_lock lock(m_sessionMapMutex);
|
||||
SessionMap::const_iterator pos = m_sessionMap.find(id);
|
||||
if (pos != m_sessionMap.end())
|
||||
tmpSession = pos->second;
|
||||
return tmpSession;
|
||||
}
|
||||
|
||||
SessionWrapper
|
||||
SessionManager::GetSessionByPlayerName(const string playerName) const
|
||||
{
|
||||
@@ -365,6 +376,26 @@ SessionManager::SendToAllSessions(SenderThread &sender, boost::shared_ptr<NetPac
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SessionManager::SendLobbyMsgToAllSessions(SenderThread &sender, boost::shared_ptr<NetPacket> packet, SessionData::State state)
|
||||
{
|
||||
boost::recursive_mutex::scoped_lock lock(m_sessionMapMutex);
|
||||
|
||||
SessionMap::iterator i = m_sessionMap.begin();
|
||||
SessionMap::iterator end = m_sessionMap.end();
|
||||
|
||||
while (i != end)
|
||||
{
|
||||
if (!i->second.sessionData.get())
|
||||
throw ServerException(__FILE__, __LINE__, ERR_NET_INVALID_SESSION, 0);
|
||||
|
||||
// Send each client (with a certain state) a copy of the packet.
|
||||
if (i->second.sessionData->GetState() == state && i->second.sessionData->WantsLobbyMsg())
|
||||
sender.Send(i->second.sessionData, boost::shared_ptr<NetPacket>(packet->Clone()));
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SessionManager::SendToAllButOneSessions(SenderThread &sender, boost::shared_ptr<NetPacket> packet, SessionId except, SessionData::State state)
|
||||
{
|
||||
|
||||
@@ -58,6 +58,7 @@ public:
|
||||
void MoveSessionToGame(ServerGameThread &game, SessionWrapper session);
|
||||
void RemoveSessionFromGame(SessionWrapper session);
|
||||
void SessionError(SessionWrapper session, int errorCode);
|
||||
void ResubscribeLobbyMsg(SessionWrapper session);
|
||||
void NotifyPlayerJoinedGame(unsigned gameId, unsigned playerId);
|
||||
void NotifyPlayerLeftGame(unsigned gameId, unsigned playerId);
|
||||
void NotifyGameAdminChanged(unsigned gameId, unsigned newAdminPlayerId);
|
||||
@@ -91,6 +92,7 @@ protected:
|
||||
typedef std::deque<boost::shared_ptr<ConnectData> > ConnectQueue;
|
||||
typedef std::deque<SessionWrapper> SessionQueue;
|
||||
typedef std::list<SessionWrapper> SessionList;
|
||||
typedef std::list<SessionId> SessionIdList;
|
||||
typedef std::map<SessionId, boost::timers::portable::microsec_timer> TimerSessionMap;
|
||||
typedef std::map<unsigned, boost::shared_ptr<ServerGameThread> > GameMap;
|
||||
typedef std::map<std::string, boost::timers::portable::microsec_timer> TimerClientAddressMap;
|
||||
@@ -116,6 +118,7 @@ protected:
|
||||
void NewSessionLoop();
|
||||
void RemoveGameLoop();
|
||||
void RemovePlayerLoop();
|
||||
void ResubscribeLobbyMsgLoop();
|
||||
void CheckSessionTimeoutsLoop();
|
||||
void UpdateAvatarClientTimerLoop();
|
||||
void CleanupAvatarCache();
|
||||
@@ -123,6 +126,7 @@ protected:
|
||||
void InternalAddGame(boost::shared_ptr<ServerGameThread> game);
|
||||
void InternalRemoveGame(boost::shared_ptr<ServerGameThread> game);
|
||||
void InternalRemovePlayer(unsigned playerId, unsigned errorCode);
|
||||
void InternalResubscribeMsg(SessionWrapper session);
|
||||
|
||||
void TerminateGames();
|
||||
|
||||
@@ -179,6 +183,8 @@ private:
|
||||
PlayerDataMap m_computerPlayers;
|
||||
mutable boost::mutex m_computerPlayersMutex;
|
||||
|
||||
SessionIdList m_resubscribeList;
|
||||
mutable boost::mutex m_resubscribeListMutex;
|
||||
|
||||
GameMap m_gameMap;
|
||||
|
||||
|
||||
@@ -50,6 +50,9 @@ public:
|
||||
void SetReadyFlag();
|
||||
void ResetReadyFlag();
|
||||
bool IsReady() const;
|
||||
void SetWantsLobbyMsg();
|
||||
void ResetWantsLobbyMsg();
|
||||
bool WantsLobbyMsg() const;
|
||||
|
||||
const std::string &GetClientAddr() const;
|
||||
void SetClientAddr(const std::string &addr);
|
||||
@@ -69,6 +72,7 @@ private:
|
||||
std::string m_clientAddr;
|
||||
ReceiveBuffer m_receiveBuffer;
|
||||
bool m_readyFlag;
|
||||
bool m_wantsLobbyMsg;
|
||||
boost::timers::portable::microsec_timer m_activityTimer;
|
||||
bool m_activityTimeoutNoticeSent;
|
||||
boost::timers::portable::microsec_timer m_autoDisconnectTimer;
|
||||
|
||||
@@ -55,6 +55,7 @@ public:
|
||||
void RemoveSession(SessionId session);
|
||||
|
||||
SessionWrapper Select(unsigned timeoutMsec);
|
||||
SessionWrapper GetSessionById(SessionId id) const;
|
||||
SessionWrapper GetSessionByPlayerName(const std::string playerName) const;
|
||||
SessionWrapper GetSessionByUniquePlayerId(unsigned uniqueId) const;
|
||||
|
||||
@@ -74,6 +75,7 @@ public:
|
||||
unsigned GetRawSessionCount();
|
||||
|
||||
void SendToAllSessions(SenderThread &sender, boost::shared_ptr<NetPacket> packet, SessionData::State state);
|
||||
void SendLobbyMsgToAllSessions(SenderThread &sender, boost::shared_ptr<NetPacket> packet, SessionData::State state);
|
||||
void SendToAllButOneSessions(SenderThread &sender, boost::shared_ptr<NetPacket> packet, SessionId except, SessionData::State state);
|
||||
|
||||
protected:
|
||||
|
||||
Reference in New Issue
Block a user