Started error handling for vote kick.
This commit is contained in:
@@ -120,8 +120,10 @@ using namespace std;
|
||||
#define NET_LEFT_OTHER_REASON 0xFFFF
|
||||
|
||||
// Reasons why ask kick was denied.
|
||||
#define NET_ASK_KICK_DENIED_TEMPORARY 0x0000
|
||||
#define NET_ASK_KICK_DENIED_OTHER_IN_PROGRESS 0x0001
|
||||
#define NET_ASK_KICK_DENIED_INVALID_STATE 0x0000
|
||||
#define NET_ASK_KICK_DENIED_TOO_FEW_PLAYERS 0x0001
|
||||
#define NET_ASK_KICK_DENIED_TEMPORARY 0x0002
|
||||
#define NET_ASK_KICK_DENIED_OTHER_IN_PROGRESS 0x0003
|
||||
#define NET_ASK_KICK_DENIED_OTHER_REASON 0xFFFF
|
||||
|
||||
// Vote types
|
||||
@@ -131,6 +133,7 @@ using namespace std;
|
||||
// Reasons why vote to kick was denied.
|
||||
#define NET_VOTE_KICK_DENIED_INVALID_PETITION 0x0000
|
||||
#define NET_VOTE_KICK_DENIED_ALREADY_VOTED 0x0001
|
||||
#define NET_VOTE_KICK_DENIED_IMPOSSIBLE 0x0002
|
||||
#define NET_VOTE_KICK_DENIED_OTHER_REASON 0xFFFF
|
||||
|
||||
// Reasons for timeout warning
|
||||
@@ -4485,6 +4488,12 @@ NetPacketAskKickPlayerDenied::SetData(const NetPacketAskKickPlayerDenied::Data &
|
||||
tmpData->playerId = htonl(inData.playerId);
|
||||
switch (inData.denyReason)
|
||||
{
|
||||
case KICK_DENIED_INVALID_STATE:
|
||||
tmpData->denyReason = htons(NET_ASK_KICK_DENIED_INVALID_STATE);
|
||||
break;
|
||||
case KICK_DENIED_TOO_FEW_PLAYERS:
|
||||
tmpData->denyReason = htons(NET_ASK_KICK_DENIED_TOO_FEW_PLAYERS);
|
||||
break;
|
||||
case KICK_DENIED_TEMPORARY:
|
||||
tmpData->denyReason = htons(NET_ASK_KICK_DENIED_TEMPORARY);
|
||||
break;
|
||||
@@ -4508,6 +4517,12 @@ NetPacketAskKickPlayerDenied::GetData(NetPacketAskKickPlayerDenied::Data &outDat
|
||||
outData.playerId = ntohl(tmpData->playerId);
|
||||
switch (ntohs(tmpData->denyReason))
|
||||
{
|
||||
case NET_ASK_KICK_DENIED_INVALID_STATE:
|
||||
outData.denyReason = KICK_DENIED_INVALID_STATE;
|
||||
break;
|
||||
case NET_ASK_KICK_DENIED_TOO_FEW_PLAYERS:
|
||||
outData.denyReason = KICK_DENIED_TOO_FEW_PLAYERS;
|
||||
break;
|
||||
case NET_ASK_KICK_DENIED_TEMPORARY:
|
||||
outData.denyReason = KICK_DENIED_TEMPORARY;
|
||||
break;
|
||||
@@ -4758,6 +4773,9 @@ NetPacketVoteKickPlayerDenied::SetData(const NetPacketVoteKickPlayerDenied::Data
|
||||
case VOTE_DENIED_ALREADY_VOTED:
|
||||
tmpData->denyReason = htons(NET_VOTE_KICK_DENIED_ALREADY_VOTED);
|
||||
break;
|
||||
case VOTE_DENIED_IMPOSSIBLE:
|
||||
tmpData->denyReason = htons(NET_VOTE_KICK_DENIED_IMPOSSIBLE);
|
||||
break;
|
||||
default:
|
||||
tmpData->denyReason = htons(NET_VOTE_KICK_DENIED_OTHER_REASON);
|
||||
break;
|
||||
@@ -4781,6 +4799,9 @@ NetPacketVoteKickPlayerDenied::GetData(NetPacketVoteKickPlayerDenied::Data &outD
|
||||
case NET_VOTE_KICK_DENIED_ALREADY_VOTED:
|
||||
outData.denyReason = VOTE_DENIED_ALREADY_VOTED;
|
||||
break;
|
||||
case NET_VOTE_KICK_DENIED_IMPOSSIBLE:
|
||||
outData.denyReason = VOTE_DENIED_IMPOSSIBLE;
|
||||
break;
|
||||
default:
|
||||
outData.denyReason = VOTE_DENIED_OTHER_REASON;
|
||||
break;
|
||||
|
||||
@@ -38,8 +38,6 @@ using namespace std;
|
||||
|
||||
//#define SERVER_TEST
|
||||
|
||||
#define SERVER_START_GAME_TIMEOUT_SEC 10
|
||||
|
||||
#ifdef SERVER_TEST
|
||||
#define SERVER_DELAY_NEXT_HAND_SEC 0
|
||||
#define SERVER_DELAY_NEXT_GAME_SEC 0
|
||||
@@ -62,6 +60,7 @@ using namespace std;
|
||||
#define SERVER_COMPUTER_ACTION_DELAY_SEC 2
|
||||
#endif
|
||||
|
||||
#define SERVER_START_GAME_TIMEOUT_SEC 10
|
||||
#define SERVER_GAME_ADMIN_WARNING_REMAINING_SEC 60
|
||||
#define SERVER_GAME_ADMIN_TIMEOUT_SEC 300 // 5 min, MUST be > SERVER_GAME_ADMIN_WARNING_REMAINING_SEC
|
||||
#define SERVER_VOTE_KICK_TIMEOUT_SEC 30
|
||||
@@ -204,20 +203,7 @@ AbstractServerGameStateReceiving::Process(ServerGameThread &server)
|
||||
NetPacketAskKickPlayer::Data askKickData;
|
||||
packet->ToNetPacketAskKickPlayer()->GetData(askKickData);
|
||||
|
||||
boost::shared_ptr<VoteKickData> voteData(server.InternalAskVoteKick(session.playerData->GetUniqueId(), askKickData.playerId));
|
||||
if (voteData)
|
||||
{
|
||||
boost::shared_ptr<NetPacket> startPetition(new NetPacketStartKickPlayerPetition);
|
||||
NetPacketStartKickPlayerPetition::Data startPetitionData;
|
||||
startPetitionData.petitionId = voteData->petitionId;
|
||||
startPetitionData.proposingPlayerId = session.playerData->GetUniqueId();
|
||||
startPetitionData.kickPlayerId = voteData->kickPlayerId;
|
||||
startPetitionData.kickTimeoutSec = SERVER_VOTE_KICK_TIMEOUT_SEC;
|
||||
startPetitionData.numVotesNeededToKick = voteData->initialNumVotesToKick;
|
||||
static_cast<NetPacketStartKickPlayerPetition *>(startPetition.get())->SetData(startPetitionData);
|
||||
server.SendToAllPlayers(startPetition, SessionData::Game);
|
||||
// TODO notify first vote.
|
||||
}
|
||||
server.InternalAskVoteKick(session, askKickData.playerId, SERVER_VOTE_KICK_TIMEOUT_SEC);
|
||||
}
|
||||
}
|
||||
else if (packet->ToNetPacketVoteKickPlayer())
|
||||
|
||||
@@ -135,6 +135,7 @@ ServerGameThread::Main()
|
||||
// Process current state.
|
||||
GetState().Process(*this);
|
||||
RemovePlayerLoop();
|
||||
VoteKickLoop();
|
||||
} while (!ShouldTerminate() && GetSessionManager().HasSessions());
|
||||
} catch (const PokerTHException &e)
|
||||
{
|
||||
@@ -167,6 +168,19 @@ ServerGameThread::RemovePlayerLoop()
|
||||
m_removePlayerList.clear();
|
||||
}
|
||||
|
||||
void
|
||||
ServerGameThread::VoteKickLoop()
|
||||
{
|
||||
/* boost::mutex::scoped_lock lock(m_voteKickMapMutex);
|
||||
// Check the list whether the player is already being kicked.
|
||||
VoteKickMap::iterator i = m_voteKickMap.begin();
|
||||
VoteKickMap::iterator end = m_voteKickMap.end();
|
||||
while (i != end)
|
||||
{
|
||||
++i;
|
||||
}*/
|
||||
}
|
||||
|
||||
void
|
||||
ServerGameThread::InternalStartGame()
|
||||
{
|
||||
@@ -226,25 +240,71 @@ ServerGameThread::InternalKickPlayer(unsigned playerId)
|
||||
MoveSessionToLobby(tmpSession, NTF_NET_REMOVED_KICKED);
|
||||
}
|
||||
|
||||
boost::shared_ptr<VoteKickData>
|
||||
ServerGameThread::InternalAskVoteKick(unsigned playerIdByWhom, unsigned playerIdWho)
|
||||
void
|
||||
ServerGameThread::InternalAskVoteKick(SessionWrapper byWhom, unsigned playerIdWho, unsigned timeoutSec)
|
||||
{
|
||||
// TODO: Check whether player is allowed to initiate vote.
|
||||
// TODO: Check whether there are more than two players.
|
||||
boost::shared_ptr<VoteKickData> voteData;
|
||||
if (IsRunning())
|
||||
if (IsRunning() && byWhom.playerData)
|
||||
{
|
||||
voteData.reset(new VoteKickData);
|
||||
voteData->petitionId = m_curPetitionId++;
|
||||
voteData->kickPlayerId = playerIdWho;
|
||||
voteData->initialNumVotesToKick = static_cast<unsigned>(ceil(GetCurNumberOfPlayers() / 3. * 2.));
|
||||
// Consider first vote.
|
||||
voteData->numVotesInFavourOfKicking = 1;
|
||||
voteData->votedPlayerIds.push_back(playerIdByWhom);
|
||||
boost::mutex::scoped_lock lock(m_voteKickMapMutex);
|
||||
m_voteKickMap.insert(VoteKickMap::value_type(voteData->petitionId, voteData));
|
||||
size_t numPlayers = GetCurNumberOfPlayers();
|
||||
if (numPlayers > 2)
|
||||
{
|
||||
// Lock the vote kick list.
|
||||
boost::mutex::scoped_lock lock(m_voteKickMapMutex);
|
||||
// Check the list whether the player is already being kicked.
|
||||
VoteKickMap::const_iterator i = m_voteKickMap.begin();
|
||||
VoteKickMap::const_iterator end = m_voteKickMap.end();
|
||||
while (i != end)
|
||||
{
|
||||
if (i->second->kickPlayerId == playerIdWho)
|
||||
break;
|
||||
++i;
|
||||
}
|
||||
if (i == end)
|
||||
{
|
||||
// Initiate a vote kick.
|
||||
unsigned playerIdByWhom = byWhom.playerData->GetUniqueId();
|
||||
boost::shared_ptr<VoteKickData> voteData(new VoteKickData);
|
||||
voteData->petitionId = m_curPetitionId++;
|
||||
voteData->kickPlayerId = playerIdWho;
|
||||
voteData->initialNumVotesToKick = static_cast<unsigned>(ceil(numPlayers / 3. * 2.));
|
||||
// Consider first vote.
|
||||
voteData->numVotesInFavourOfKicking = 1;
|
||||
voteData->votedPlayerIds.push_back(playerIdByWhom);
|
||||
m_voteKickMap.insert(VoteKickMap::value_type(voteData->petitionId, voteData));
|
||||
lock.unlock(); // Do not block the list longer than necessary.
|
||||
|
||||
boost::shared_ptr<NetPacket> startPetition(new NetPacketStartKickPlayerPetition);
|
||||
NetPacketStartKickPlayerPetition::Data startPetitionData;
|
||||
startPetitionData.petitionId = voteData->petitionId;
|
||||
startPetitionData.proposingPlayerId = playerIdByWhom;
|
||||
startPetitionData.kickPlayerId = voteData->kickPlayerId;
|
||||
startPetitionData.kickTimeoutSec = timeoutSec;
|
||||
startPetitionData.numVotesNeededToKick = voteData->initialNumVotesToKick;
|
||||
static_cast<NetPacketStartKickPlayerPetition *>(startPetition.get())->SetData(startPetitionData);
|
||||
SendToAllPlayers(startPetition, SessionData::Game);
|
||||
}
|
||||
else
|
||||
{
|
||||
lock.unlock(); // Do not block the list longer than necessary.
|
||||
InternalDenyAskVoteKick(byWhom, playerIdWho, KICK_DENIED_OTHER_IN_PROGRESS);
|
||||
}
|
||||
}
|
||||
else
|
||||
InternalDenyAskVoteKick(byWhom, playerIdWho, KICK_DENIED_TOO_FEW_PLAYERS);
|
||||
}
|
||||
return voteData;
|
||||
else
|
||||
InternalDenyAskVoteKick(byWhom, playerIdWho, KICK_DENIED_INVALID_STATE);
|
||||
}
|
||||
|
||||
void
|
||||
ServerGameThread::InternalDenyAskVoteKick(SessionWrapper byWhom, unsigned playerIdWho, DenyKickPlayerReason reason)
|
||||
{
|
||||
boost::shared_ptr<NetPacket> denyPetition(new NetPacketAskKickPlayerDenied);
|
||||
NetPacketAskKickPlayerDenied::Data denyPetitionData;
|
||||
denyPetitionData.playerId = playerIdWho;
|
||||
denyPetitionData.denyReason = reason;
|
||||
static_cast<NetPacketAskKickPlayerDenied *>(denyPetition.get())->SetData(denyPetitionData);
|
||||
GetSender().Send(byWhom.sessionData, denyPetition);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -82,12 +82,14 @@ protected:
|
||||
// Main function of the thread.
|
||||
virtual void Main();
|
||||
void RemovePlayerLoop();
|
||||
void VoteKickLoop();
|
||||
|
||||
void InternalStartGame();
|
||||
void ResetGame();
|
||||
|
||||
void InternalKickPlayer(unsigned playerId);
|
||||
boost::shared_ptr<VoteKickData> InternalAskVoteKick(unsigned playerIdByWhom, unsigned playerIdWho);
|
||||
void InternalAskVoteKick(SessionWrapper byWhom, unsigned playerIdWho, unsigned timeoutSec);
|
||||
void InternalDenyAskVoteKick(SessionWrapper byWhom, unsigned playerIdWho, DenyKickPlayerReason reason);
|
||||
void InternalVoteKick(unsigned petitionId, KickVote vote);
|
||||
|
||||
PlayerDataList GetFullPlayerDataList() const;
|
||||
|
||||
Reference in New Issue
Block a user