More work on spectator mode.

This commit is contained in:
lotodore
2013-06-16 10:43:13 +02:00
parent 6e55351389
commit 00543b7560
13 changed files with 271 additions and 45 deletions
+8 -3
View File
@@ -108,10 +108,15 @@ ServerGame::GetCreatorDBId() const
}
void
ServerGame::AddSession(boost::shared_ptr<SessionData> session)
ServerGame::AddSession(boost::shared_ptr<SessionData> session, bool spectateOnly)
{
if (session)
GetState().HandleNewSession(shared_from_this(), session);
if (session) {
if (spectateOnly) {
GetState().HandleNewSpectator(shared_from_this(), session);
} else {
GetState().HandleNewPlayer(shared_from_this(), session);
}
}
}
void
+46 -11
View File
@@ -384,13 +384,25 @@ AbstractServerGameStateReceiving::CreateNetPacketPlayerJoined(unsigned gameId, c
}
boost::shared_ptr<NetPacket>
AbstractServerGameStateReceiving::CreateNetPacketJoinGameAck(const ServerGame &server, const PlayerData &playerData)
AbstractServerGameStateReceiving::CreateNetPacketSpectatorJoined(unsigned gameId, const PlayerData &playerData)
{
boost::shared_ptr<NetPacket> packet(new NetPacket);
packet->GetMsg()->set_messagetype(PokerTHMessage::Type_GameSpectatorJoinedMessage);
GameSpectatorJoinedMessage *netGameSpectator = packet->GetMsg()->mutable_gamespectatorjoinedmessage();
netGameSpectator->set_gameid(gameId);
netGameSpectator->set_playerid(playerData.GetUniqueId());
return packet;
}
boost::shared_ptr<NetPacket>
AbstractServerGameStateReceiving::CreateNetPacketJoinGameAck(const ServerGame &server, const PlayerData &playerData, bool spectateOnly)
{
boost::shared_ptr<NetPacket> packet(new NetPacket);
packet->GetMsg()->set_messagetype(PokerTHMessage::Type_JoinGameAckMessage);
JoinGameAckMessage *netJoinReply = packet->GetMsg()->mutable_joingameackmessage();
netJoinReply->set_gameid(server.GetId());
netJoinReply->set_areyougameadmin(playerData.IsGameAdmin());
netJoinReply->set_spectateonly(spectateOnly);
NetGameInfo *gameInfo = netJoinReply->mutable_gameinfo();
NetPacket::SetGameData(server.GetGameData(), *gameInfo);
@@ -399,13 +411,13 @@ AbstractServerGameStateReceiving::CreateNetPacketJoinGameAck(const ServerGame &s
}
void
AbstractServerGameStateReceiving::AcceptNewSession(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session)
AbstractServerGameStateReceiving::AcceptNewSession(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session, bool spectateOnly)
{
// Set game admin, if applicable.
session->GetPlayerData()->SetGameAdmin(session->GetPlayerData()->GetUniqueId() == server->GetAdminPlayerId());
// Send ack to client.
server->GetLobbyThread().GetSender().Send(session, CreateNetPacketJoinGameAck(*server, *session->GetPlayerData()));
server->GetLobbyThread().GetSender().Send(session, CreateNetPacketJoinGameAck(*server, *session->GetPlayerData(), spectateOnly));
// Send notifications for connected players to client.
PlayerDataList tmpPlayerList(server->GetFullPlayerDataList());
@@ -416,14 +428,22 @@ AbstractServerGameStateReceiving::AcceptNewSession(boost::shared_ptr<ServerGame>
++player_i;
}
// Send "Player Joined" to other fully connected clients.
server->SendToAllPlayers(CreateNetPacketPlayerJoined(server->GetId(), *session->GetPlayerData()), SessionData::Game);
// Send "Player Joined"/"Spectator Joined" to other fully connected clients.
if (spectateOnly) {
server->SendToAllPlayers(CreateNetPacketSpectatorJoined(server->GetId(), *session->GetPlayerData()), SessionData::Game);
} else {
server->SendToAllPlayers(CreateNetPacketPlayerJoined(server->GetId(), *session->GetPlayerData()), SessionData::Game);
}
// Accept session.
server->GetSessionManager().AddSession(session);
// Notify lobby.
server->GetLobbyThread().NotifyPlayerJoinedGame(server->GetId(), session->GetPlayerData()->GetUniqueId());
if (spectateOnly) {
server->GetLobbyThread().NotifySpectatorJoinedGame(server->GetId(), session->GetPlayerData()->GetUniqueId());
} else {
server->GetLobbyThread().NotifyPlayerJoinedGame(server->GetId(), session->GetPlayerData()->GetUniqueId());
}
}
//-----------------------------------------------------------------------------
@@ -471,7 +491,7 @@ ServerGameStateInit::NotifySessionRemoved(boost::shared_ptr<ServerGame> server)
}
void
ServerGameStateInit::HandleNewSession(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session)
ServerGameStateInit::HandleNewPlayer(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session)
{
if (session && session->GetPlayerData()) {
const GameData &tmpGameData = server->GetGameData();
@@ -480,7 +500,7 @@ ServerGameStateInit::HandleNewSession(boost::shared_ptr<ServerGame> server, boos
server->MoveSessionToLobby(session, NTF_NET_REMOVED_GAME_FULL);
} else {
AcceptNewSession(server, session);
AcceptNewSession(server, session, false);
if (server->GetCurNumberOfPlayers() == tmpGameData.maxNumberOfPlayers) {
// Automatically start the game if it is full.
@@ -490,6 +510,11 @@ ServerGameStateInit::HandleNewSession(boost::shared_ptr<ServerGame> server, boos
}
}
void
ServerGameStateInit::HandleNewSpectator(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session)
{
}
void
ServerGameStateInit::RegisterAdminTimer(boost::shared_ptr<ServerGame> server)
{
@@ -701,12 +726,17 @@ ServerGameStateStartGame::Exit(boost::shared_ptr<ServerGame> server)
}
void
ServerGameStateStartGame::HandleNewSession(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session)
ServerGameStateStartGame::HandleNewPlayer(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session)
{
// Do not accept new sessions in this state.
server->MoveSessionToLobby(session, NTF_NET_REMOVED_ALREADY_RUNNING);
}
void
ServerGameStateStartGame::HandleNewSpectator(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session)
{
}
void
ServerGameStateStartGame::InternalProcessPacket(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session, boost::shared_ptr<NetPacket> packet)
{
@@ -774,7 +804,7 @@ AbstractServerGameStateRunning::~AbstractServerGameStateRunning()
}
void
AbstractServerGameStateRunning::HandleNewSession(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session)
AbstractServerGameStateRunning::HandleNewPlayer(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session)
{
// Verify that the user is allowed to rejoin.
@@ -782,7 +812,7 @@ AbstractServerGameStateRunning::HandleNewSession(boost::shared_ptr<ServerGame> s
boost::shared_ptr<PlayerInterface> tmpPlayer = server->GetPlayerInterfaceFromGame(session->GetPlayerData()->GetName());
if (tmpPlayer && tmpPlayer->getMyGuid() == session->GetPlayerData()->GetOldGuid()) {
// The player wants to rejoin.
AcceptNewSession(server, session);
AcceptNewSession(server, session, false);
// Remember: We need to initiate a rejoin when starting the next hand.
server->AddRejoinPlayer(session->GetPlayerData()->GetUniqueId());
@@ -802,6 +832,11 @@ AbstractServerGameStateRunning::HandleNewSession(boost::shared_ptr<ServerGame> s
}
}
void
AbstractServerGameStateRunning::HandleNewSpectator(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session)
{
}
void
AbstractServerGameStateRunning::InternalProcessPacket(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session, boost::shared_ptr<NetPacket> packet)
{
+37 -7
View File
@@ -367,18 +367,18 @@ ServerLobbyThread::ReAddSession(boost::shared_ptr<SessionData> session, int reas
}
void
ServerLobbyThread::MoveSessionToGame(boost::shared_ptr<ServerGame> game, boost::shared_ptr<SessionData> session, bool autoLeave)
ServerLobbyThread::MoveSessionToGame(boost::shared_ptr<ServerGame> game, boost::shared_ptr<SessionData> session, bool autoLeave, bool spectateOnly)
{
// Remove session from the lobby.
m_sessionManager.RemoveSession(session->GetId());
// Session is now in game state.
session->SetState(SessionData::Game);
session->SetState(spectateOnly ? SessionData::Spectating: SessionData::Game);
// Store it in the list of game sessions.
m_gameSessionManager.AddSession(session);
// Set the game id of the session.
session->SetGame(game);
// Add session to the game.
game->AddSession(session);
game->AddSession(session, spectateOnly);
// Optionally enable auto leave after game finish.
if (autoLeave)
game->SetPlayerAutoLeaveOnFinish(session->GetPlayerData()->GetUniqueId());
@@ -465,6 +465,34 @@ ServerLobbyThread::NotifyPlayerLeftGame(unsigned gameId, unsigned playerId)
m_gameSessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Game);
}
void
ServerLobbyThread::NotifySpectatorJoinedGame(unsigned gameId, unsigned playerId)
{
// Send notification to players in lobby.
boost::shared_ptr<NetPacket> packet(new NetPacket);
packet->GetMsg()->set_messagetype(PokerTHMessage::Type_GameListSpectatorJoinedMessage);
GameListSpectatorJoinedMessage *netListMsg = packet->GetMsg()->mutable_gamelistspectatorjoinedmessage();
netListMsg->set_gameid(gameId);
netListMsg->set_playerid(playerId);
m_sessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Established);
m_gameSessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Game);
}
void
ServerLobbyThread::NotifySpectatorLeftGame(unsigned gameId, unsigned playerId)
{
// Send notification to players in lobby.
boost::shared_ptr<NetPacket> packet(new NetPacket);
packet->GetMsg()->set_messagetype(PokerTHMessage::Type_GameListSpectatorLeftMessage);
GameListSpectatorLeftMessage *netListMsg = packet->GetMsg()->mutable_gamelistspectatorleftmessage();
netListMsg->set_gameid(gameId);
netListMsg->set_playerid(playerId);
m_sessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Established);
m_gameSessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Game);
}
void
ServerLobbyThread::NotifyGameAdminChanged(unsigned gameId, unsigned newAdminPlayerId)
{
@@ -1315,7 +1343,7 @@ ServerLobbyThread::HandleNetPacketCreateGame(boost::shared_ptr<SessionData> sess
// Add game to list of games.
InternalAddGame(game);
MoveSessionToGame(game, session, newGame.autoleave());
MoveSessionToGame(game, session, newGame.autoleave(), false);
}
}
@@ -1332,8 +1360,9 @@ ServerLobbyThread::HandleNetPacketJoinGame(boost::shared_ptr<SessionData> sessio
if (pos != m_gameMap.end()) {
boost::shared_ptr<ServerGame> game = pos->second;
const GameData &tmpData = game->GetGameData();
// As guest, you are only allowed to join normal games or to join as spectator.
if (session->GetPlayerData()->GetRights() == PLAYER_RIGHTS_GUEST
&& tmpData.gameType != GAME_TYPE_NORMAL) {
&& tmpData.gameType != GAME_TYPE_NORMAL && !joinGame.spectateonly()) {
SendJoinGameFailed(session, joinGame.gameid(), NTF_NET_JOIN_GUEST_FORBIDDEN);
} else if (tmpData.gameType == GAME_TYPE_INVITE_ONLY
&& !game->IsPlayerInvited(session->GetPlayerData()->GetUniqueId())) {
@@ -1341,13 +1370,14 @@ ServerLobbyThread::HandleNetPacketJoinGame(boost::shared_ptr<SessionData> sessio
} else if (!game->CheckPassword(password)) {
SendJoinGameFailed(session, joinGame.gameid(), NTF_NET_JOIN_INVALID_PASSWORD);
} else if (tmpData.gameType == GAME_TYPE_RANKING
&& !joinGame.spectateonly()
&& session->GetClientAddr() != SERVER_ADDRESS_LOCALHOST_STR
&& session->GetClientAddr() != SERVER_ADDRESS_LOCALHOST_STR_V4V6
&& session->GetClientAddr() != SERVER_ADDRESS_LOCALHOST_STR_V4
&& game->IsClientAddressConnected(session->GetClientAddr())) {
SendJoinGameFailed(session, joinGame.gameid(), NTF_NET_JOIN_IP_BLOCKED);
} else {
MoveSessionToGame(game, session, joinGame.autoleave());
MoveSessionToGame(game, session, joinGame.autoleave(), joinGame.spectateonly());
}
} else {
SendJoinGameFailed(session, joinGame.gameid(), NTF_NET_JOIN_GAME_INVALID);
@@ -1362,7 +1392,7 @@ ServerLobbyThread::HandleNetPacketRejoinGame(boost::shared_ptr<SessionData> sess
if (pos != m_gameMap.end()) {
boost::shared_ptr<ServerGame> game = pos->second;
MoveSessionToGame(game, session, rejoinGame.autoleave());
MoveSessionToGame(game, session, rejoinGame.autoleave(), false);
} else {
SendJoinGameFailed(session, rejoinGame.gameid(), NTF_NET_JOIN_GAME_INVALID);
}
+8 -8
View File
@@ -169,7 +169,7 @@ SessionManager::GetPlayerDataList() const
}
PlayerIdList
SessionManager::GetPlayerIdList(SessionData::State state) const
SessionManager::GetPlayerIdList(int state) const
{
PlayerIdList playerList;
boost::recursive_mutex::scoped_lock lock(m_sessionMapMutex);
@@ -179,7 +179,7 @@ SessionManager::GetPlayerIdList(SessionData::State state) const
while (session_i != session_end) {
// Get all players in the game.
if (session_i->second->GetState() == state) {
if (session_i->second->GetState() & state != 0) {
playerList.push_back(session_i->second->GetPlayerData()->GetUniqueId());
}
++session_i;
@@ -319,7 +319,7 @@ SessionManager::GetEstablishedSessionCount()
}
void
SessionManager::SendToAllSessions(SenderHelper &sender, boost::shared_ptr<NetPacket> packet, SessionData::State state)
SessionManager::SendToAllSessions(SenderHelper &sender, boost::shared_ptr<NetPacket> packet, int state)
{
boost::recursive_mutex::scoped_lock lock(m_sessionMapMutex);
@@ -331,14 +331,14 @@ SessionManager::SendToAllSessions(SenderHelper &sender, boost::shared_ptr<NetPac
throw ServerException(__FILE__, __LINE__, ERR_NET_INVALID_SESSION, 0);
// Send each client (with a certain state) a copy of the packet.
if (i->second->GetState() == state)
if (i->second->GetState() & state != 0)
sender.Send(i->second, packet);
++i;
}
}
void
SessionManager::SendLobbyMsgToAllSessions(SenderHelper &sender, boost::shared_ptr<NetPacket> packet, SessionData::State state)
SessionManager::SendLobbyMsgToAllSessions(SenderHelper &sender, boost::shared_ptr<NetPacket> packet, int state)
{
boost::recursive_mutex::scoped_lock lock(m_sessionMapMutex);
@@ -350,14 +350,14 @@ SessionManager::SendLobbyMsgToAllSessions(SenderHelper &sender, boost::shared_pt
throw ServerException(__FILE__, __LINE__, ERR_NET_INVALID_SESSION, 0);
// Send each client (with a certain state) a copy of the packet.
if (i->second->GetState() == state && i->second->WantsLobbyMsg())
if (i->second->GetState() & state != 0 && i->second->WantsLobbyMsg())
sender.Send(i->second, packet);
++i;
}
}
void
SessionManager::SendToAllButOneSessions(SenderHelper &sender, boost::shared_ptr<NetPacket> packet, SessionId except, SessionData::State state)
SessionManager::SendToAllButOneSessions(SenderHelper &sender, boost::shared_ptr<NetPacket> packet, SessionId except, int state)
{
boost::recursive_mutex::scoped_lock lock(m_sessionMapMutex);
@@ -366,7 +366,7 @@ SessionManager::SendToAllButOneSessions(SenderHelper &sender, boost::shared_ptr<
while (i != end) {
// Send each fully connected client but one a copy of the packet.
if (i->second->GetState() == state)
if (i->second->GetState() & state != 0)
if (i->first != except)
sender.Send(i->second, packet);
++i;