Pass on admin state if the admin leaves the network game, so that someone else can start the game.
This commit is contained in:
@@ -50,6 +50,7 @@ public:
|
||||
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 SignalNetClientNewGameAdmin(unsigned playerId, const std::string &playerName) = 0;
|
||||
|
||||
virtual void SignalNetClientChatMsg(const std::string &playerName, const std::string &msg) = 0;
|
||||
virtual void SignalNetClientWaitDialog() = 0;
|
||||
|
||||
@@ -86,6 +86,7 @@ protected:
|
||||
bool GetCachedPlayerInfo(unsigned id, PlayerInfo &info) const;
|
||||
void RequestPlayerInfo(unsigned id);
|
||||
void SetPlayerInfo(unsigned id, const PlayerInfo &info);
|
||||
void SetNewGameAdmin(unsigned id);
|
||||
|
||||
const ClientContext &GetContext() const;
|
||||
ClientContext &GetContext();
|
||||
|
||||
@@ -401,14 +401,6 @@ AbstractClientStateReceiving::Process(ClientThread &client)
|
||||
client.GetCallback().SignalNetClientRemovedFromGame(removedData.removeReason);
|
||||
client.SetState(ClientStateWaitJoin::Instance());
|
||||
}
|
||||
else if (tmpPacket->ToNetPacketError())
|
||||
{
|
||||
// Server reported an error.
|
||||
NetPacketError::Data errorData;
|
||||
tmpPacket->ToNetPacketError()->GetData(errorData);
|
||||
// Show the error.
|
||||
throw ClientException(errorData.errorCode, 0);
|
||||
}
|
||||
else if (tmpPacket->ToNetPacketChatText())
|
||||
{
|
||||
// Chat message - display it in the GUI.
|
||||
@@ -428,6 +420,15 @@ AbstractClientStateReceiving::Process(ClientThread &client)
|
||||
// Signal to GUI and remove from data list.
|
||||
client.RemovePlayerData(playerLeftData.playerId);
|
||||
}
|
||||
else if (tmpPacket->ToNetPacketGameAdminChanged())
|
||||
{
|
||||
// New admin for the game.
|
||||
NetPacketGameAdminChanged::Data adminChangedData;
|
||||
tmpPacket->ToNetPacketGameAdminChanged()->GetData(adminChangedData);
|
||||
|
||||
// Set new game admin and signal to GUI.
|
||||
client.SetNewGameAdmin(adminChangedData.playerId);
|
||||
}
|
||||
else if (tmpPacket->ToNetPacketGameListNew())
|
||||
{
|
||||
// A new game was created on the server.
|
||||
@@ -478,6 +479,14 @@ AbstractClientStateReceiving::Process(ClientThread &client)
|
||||
tmpPacket->ToNetPacketGameListPlayerLeft()->GetData(playerLeftData);
|
||||
client.ModifyGameInfoRemovePlayer(playerLeftData.gameId, playerLeftData.playerId);
|
||||
}
|
||||
else if (tmpPacket->ToNetPacketError())
|
||||
{
|
||||
// Server reported an error.
|
||||
NetPacketError::Data errorData;
|
||||
tmpPacket->ToNetPacketError()->GetData(errorData);
|
||||
// Show the error.
|
||||
throw ClientException(errorData.errorCode, 0);
|
||||
}
|
||||
else
|
||||
retVal = InternalProcess(client, tmpPacket);
|
||||
}
|
||||
|
||||
@@ -404,6 +404,18 @@ ClientThread::SetPlayerInfo(unsigned id, const PlayerInfo &info)
|
||||
GetCallback().SignalNetClientPlayerChanged(id, info.playerName);
|
||||
}
|
||||
|
||||
void
|
||||
ClientThread::SetNewGameAdmin(unsigned id)
|
||||
{
|
||||
// Update player data for current game.
|
||||
boost::shared_ptr<PlayerData> playerData = GetPlayerDataByUniqueId(id);
|
||||
if (playerData.get())
|
||||
{
|
||||
playerData->SetRights(PLAYER_RIGHTS_ADMIN);
|
||||
GetCallback().SignalNetClientNewGameAdmin(id, playerData->GetName());
|
||||
}
|
||||
}
|
||||
|
||||
const ClientContext &
|
||||
ClientThread::GetContext() const
|
||||
{
|
||||
|
||||
@@ -41,22 +41,23 @@ using namespace std;
|
||||
#define NET_TYPE_JOIN_GAME_FAILED 0x000C
|
||||
#define NET_TYPE_PLAYER_JOINED 0x000D
|
||||
#define NET_TYPE_PLAYER_LEFT 0x000E
|
||||
#define NET_TYPE_KICK_PLAYER 0x000F
|
||||
#define NET_TYPE_LEAVE_CURRENT_GAME 0x0010
|
||||
#define NET_TYPE_START_EVENT 0x0011
|
||||
#define NET_TYPE_GAME_START 0x0012
|
||||
#define NET_TYPE_HAND_START 0x0013
|
||||
#define NET_TYPE_PLAYERS_TURN 0x0014
|
||||
#define NET_TYPE_PLAYERS_ACTION 0x0015
|
||||
#define NET_TYPE_PLAYERS_ACTION_DONE 0x0016
|
||||
#define NET_TYPE_PLAYERS_ACTION_REJECTED 0x0017
|
||||
#define NET_TYPE_DEAL_FLOP_CARDS 0x0018
|
||||
#define NET_TYPE_DEAL_TURN_CARD 0x0019
|
||||
#define NET_TYPE_DEAL_RIVER_CARD 0x001A
|
||||
#define NET_TYPE_ALL_IN_SHOW_CARDS 0x001B
|
||||
#define NET_TYPE_END_OF_HAND_SHOW_CARDS 0x001C
|
||||
#define NET_TYPE_END_OF_HAND_HIDE_CARDS 0x001D
|
||||
#define NET_TYPE_END_OF_GAME 0x001E
|
||||
#define NET_TYPE_GAME_ADMIN_CHANGED 0x000F
|
||||
#define NET_TYPE_KICK_PLAYER 0x0010
|
||||
#define NET_TYPE_LEAVE_CURRENT_GAME 0x0011
|
||||
#define NET_TYPE_START_EVENT 0x0012
|
||||
#define NET_TYPE_GAME_START 0x0013
|
||||
#define NET_TYPE_HAND_START 0x0014
|
||||
#define NET_TYPE_PLAYERS_TURN 0x0015
|
||||
#define NET_TYPE_PLAYERS_ACTION 0x0016
|
||||
#define NET_TYPE_PLAYERS_ACTION_DONE 0x0017
|
||||
#define NET_TYPE_PLAYERS_ACTION_REJECTED 0x0018
|
||||
#define NET_TYPE_DEAL_FLOP_CARDS 0x0019
|
||||
#define NET_TYPE_DEAL_TURN_CARD 0x001A
|
||||
#define NET_TYPE_DEAL_RIVER_CARD 0x001B
|
||||
#define NET_TYPE_ALL_IN_SHOW_CARDS 0x001C
|
||||
#define NET_TYPE_END_OF_HAND_SHOW_CARDS 0x001D
|
||||
#define NET_TYPE_END_OF_HAND_HIDE_CARDS 0x001E
|
||||
#define NET_TYPE_END_OF_GAME 0x001F
|
||||
|
||||
#define NET_TYPE_REMOVED_FROM_GAME 0x0100
|
||||
|
||||
@@ -239,6 +240,12 @@ struct GCC_PACKED NetPacketPlayerLeftData
|
||||
u_int32_t playerId;
|
||||
};
|
||||
|
||||
struct GCC_PACKED NetPacketGameAdminChangedData
|
||||
{
|
||||
NetPacketHeader head;
|
||||
u_int32_t playerId;
|
||||
};
|
||||
|
||||
struct GCC_PACKED NetPacketKickPlayerData
|
||||
{
|
||||
NetPacketHeader head;
|
||||
@@ -582,6 +589,9 @@ NetPacket::Create(char *data, unsigned &dataSize)
|
||||
case NET_TYPE_PLAYER_LEFT:
|
||||
tmpPacket = boost::shared_ptr<NetPacket>(new NetPacketPlayerLeft);
|
||||
break;
|
||||
case NET_TYPE_GAME_ADMIN_CHANGED:
|
||||
tmpPacket = boost::shared_ptr<NetPacket>(new NetPacketGameAdminChanged);
|
||||
break;
|
||||
case NET_TYPE_KICK_PLAYER:
|
||||
tmpPacket = boost::shared_ptr<NetPacket>(new NetPacketKickPlayer);
|
||||
break;
|
||||
@@ -810,6 +820,12 @@ NetPacket::ToNetPacketPlayerLeft() const
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const NetPacketGameAdminChanged *
|
||||
NetPacket::ToNetPacketGameAdminChanged() const
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const NetPacketKickPlayer *
|
||||
NetPacket::ToNetPacketKickPlayer() const
|
||||
{
|
||||
@@ -2189,6 +2205,65 @@ NetPacketPlayerLeft::InternalCheck(const NetPacketHeader*) const
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NetPacketGameAdminChanged::NetPacketGameAdminChanged()
|
||||
: NetPacket(NET_TYPE_GAME_ADMIN_CHANGED, sizeof(NetPacketGameAdminChangedData), sizeof(NetPacketGameAdminChangedData))
|
||||
{
|
||||
}
|
||||
|
||||
NetPacketGameAdminChanged::~NetPacketGameAdminChanged()
|
||||
{
|
||||
}
|
||||
|
||||
boost::shared_ptr<NetPacket>
|
||||
NetPacketGameAdminChanged::Clone() const
|
||||
{
|
||||
boost::shared_ptr<NetPacket> newPacket(new NetPacketGameAdminChanged);
|
||||
try
|
||||
{
|
||||
newPacket->SetRawData(GetRawData());
|
||||
} catch (const NetException &)
|
||||
{
|
||||
// Need to return the new packet anyway.
|
||||
}
|
||||
return newPacket;
|
||||
}
|
||||
|
||||
void
|
||||
NetPacketGameAdminChanged::SetData(const NetPacketGameAdminChanged::Data &inData)
|
||||
{
|
||||
NetPacketGameAdminChangedData *tmpData = (NetPacketGameAdminChangedData *)GetRawData();
|
||||
|
||||
// Set the data.
|
||||
tmpData->playerId = htonl(inData.playerId);
|
||||
|
||||
// Check the packet - just in case.
|
||||
Check(GetRawData());
|
||||
}
|
||||
|
||||
void
|
||||
NetPacketGameAdminChanged::GetData(NetPacketGameAdminChanged::Data &outData) const
|
||||
{
|
||||
// We assume that the data is valid. Validity has already been checked.
|
||||
NetPacketGameAdminChangedData *tmpData = (NetPacketGameAdminChangedData *)GetRawData();
|
||||
|
||||
outData.playerId = ntohl(tmpData->playerId);
|
||||
}
|
||||
|
||||
const NetPacketGameAdminChanged *
|
||||
NetPacketGameAdminChanged::ToNetPacketGameAdminChanged() const
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
NetPacketGameAdminChanged::InternalCheck(const NetPacketHeader*) const
|
||||
{
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NetPacketKickPlayer::NetPacketKickPlayer()
|
||||
|
||||
@@ -312,10 +312,14 @@ ServerGameStateInit::InternalProcess(ServerGameThread &server, SessionWrapper se
|
||||
}
|
||||
else if (packet->ToNetPacketKickPlayer())
|
||||
{
|
||||
NetPacketKickPlayer::Data kickPlayerData;
|
||||
packet->ToNetPacketKickPlayer()->GetData(kickPlayerData);
|
||||
// Only admins are allowed to kick.
|
||||
if (session.playerData->GetRights() == PLAYER_RIGHTS_ADMIN)
|
||||
{
|
||||
NetPacketKickPlayer::Data kickPlayerData;
|
||||
packet->ToNetPacketKickPlayer()->GetData(kickPlayerData);
|
||||
|
||||
server.InternalKickPlayer(kickPlayerData.playerId);
|
||||
server.InternalKickPlayer(kickPlayerData.playerId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -300,6 +300,23 @@ ServerGameThread::GracefulRemoveSession(SessionWrapper session)
|
||||
static_cast<NetPacketPlayerLeft *>(thisPlayerLeft.get())->SetData(thisPlayerLeftData);
|
||||
GetSessionManager().SendToAllSessions(GetSender(), thisPlayerLeft, SessionData::Game);
|
||||
|
||||
if (tmpPlayerData->GetRights() == PLAYER_RIGHTS_ADMIN)
|
||||
{
|
||||
// Find new admin for the game
|
||||
PlayerIdList idList(GetSessionManager().GetPlayerIdList());
|
||||
if (!idList.empty())
|
||||
{
|
||||
// Send "Game Admin Changed" to clients.
|
||||
boost::shared_ptr<NetPacket> adminChanged(new NetPacketGameAdminChanged);
|
||||
NetPacketGameAdminChanged::Data adminChangedData;
|
||||
adminChangedData.playerId = idList.front(); // Choose next player as admin.
|
||||
static_cast<NetPacketGameAdminChanged *>(adminChanged.get())->SetData(adminChangedData);
|
||||
GetSessionManager().SendToAllSessions(GetSender(), adminChanged, SessionData::Game);
|
||||
}
|
||||
}
|
||||
// Reset player rights.
|
||||
tmpPlayerData->SetRights(PLAYER_RIGHTS_NORMAL);
|
||||
|
||||
GetLobbyThread().NotifyPlayerLeftGame(GetId(), session.playerData->GetUniqueId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ class NetPacketJoinGameAck;
|
||||
class NetPacketJoinGameFailed;
|
||||
class NetPacketPlayerJoined;
|
||||
class NetPacketPlayerLeft;
|
||||
class NetPacketGameAdminChanged;
|
||||
class NetPacketKickPlayer;
|
||||
class NetPacketLeaveCurrentGame;
|
||||
class NetPacketStartEvent;
|
||||
@@ -108,6 +109,7 @@ public:
|
||||
virtual const NetPacketJoinGameFailed *ToNetPacketJoinGameFailed() const;
|
||||
virtual const NetPacketPlayerJoined *ToNetPacketPlayerJoined() const;
|
||||
virtual const NetPacketPlayerLeft *ToNetPacketPlayerLeft() const;
|
||||
virtual const NetPacketGameAdminChanged *ToNetPacketGameAdminChanged() const;
|
||||
virtual const NetPacketKickPlayer *ToNetPacketKickPlayer() const;
|
||||
virtual const NetPacketLeaveCurrentGame *ToNetPacketLeaveCurrentGame() const;
|
||||
virtual const NetPacketStartEvent *ToNetPacketStartEvent() const;
|
||||
@@ -484,6 +486,29 @@ protected:
|
||||
virtual void InternalCheck(const NetPacketHeader* data) const;
|
||||
};
|
||||
|
||||
class NetPacketGameAdminChanged : public NetPacket
|
||||
{
|
||||
public:
|
||||
struct Data
|
||||
{
|
||||
u_int32_t playerId;
|
||||
};
|
||||
|
||||
NetPacketGameAdminChanged();
|
||||
virtual ~NetPacketGameAdminChanged();
|
||||
|
||||
virtual boost::shared_ptr<NetPacket> Clone() const;
|
||||
|
||||
void SetData(const Data &inData);
|
||||
void GetData(Data &outData) const;
|
||||
|
||||
virtual const NetPacketGameAdminChanged *ToNetPacketGameAdminChanged() const;
|
||||
|
||||
protected:
|
||||
|
||||
virtual void InternalCheck(const NetPacketHeader* data) const;
|
||||
};
|
||||
|
||||
class NetPacketKickPlayer : public NetPacket
|
||||
{
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user