Pass on admin state if the admin leaves the network game, so that someone else can start the game.

This commit is contained in:
lotodore
2007-10-03 13:36:47 +00:00
parent 8385b2e28d
commit 076d44b0ae
19 changed files with 239 additions and 49 deletions
+17 -8
View File
@@ -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);
}
+12
View File
@@ -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
{
+91 -16
View File
@@ -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()
+7 -3
View File
@@ -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
{
+17
View File
@@ -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());
}
}