More work on vote kick. Some network packets are exchanged, but still not functional.
This commit is contained in:
@@ -22,6 +22,7 @@
|
|||||||
#define _GAMEDATA_H_
|
#define _GAMEDATA_H_
|
||||||
|
|
||||||
#include <playerdata.h>
|
#include <playerdata.h>
|
||||||
|
#include <third_party/boost/timers.hpp>
|
||||||
|
|
||||||
#define SERVER_COMPUTER_PLAYER_NAME "Computer"
|
#define SERVER_COMPUTER_PLAYER_NAME "Computer"
|
||||||
|
|
||||||
@@ -87,5 +88,14 @@ struct StartData
|
|||||||
int numberOfPlayers;
|
int numberOfPlayers;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct VoteKickData
|
||||||
|
{
|
||||||
|
unsigned petitionId;
|
||||||
|
unsigned kickPlayerId;
|
||||||
|
unsigned numVotesToKick;
|
||||||
|
boost::timers::portable::microsec_timer voteTimer;
|
||||||
|
std::list<unsigned> votedPlayerIds;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -3088,8 +3088,14 @@ void gameTableImpl::leaveCurrentNetworkGame() {
|
|||||||
|
|
||||||
void gameTableImpl::triggerVoteOnKick(int id) {
|
void gameTableImpl::triggerVoteOnKick(int id) {
|
||||||
|
|
||||||
qDebug() << "vote for kick user: " << id;
|
assert(myStartWindow->getSession()->getCurrentGame());
|
||||||
// myStartWindow->getSession()->sendVoteKickSignal(id);
|
int playerCount = static_cast<int>(myStartWindow->getSession()->getCurrentGame()->getSeatsList()->size());
|
||||||
|
if (id < playerCount)
|
||||||
|
{
|
||||||
|
PlayerListIterator pos = myStartWindow->getSession()->getCurrentGame()->getSeatsList()->begin();
|
||||||
|
advance(pos, id);
|
||||||
|
myStartWindow->getSession()->startVoteKickPlayer((*pos)->getMyUniqueID());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gameTableImpl::startVoteOnKick(int playerId, int timeoutSec)
|
void gameTableImpl::startVoteOnKick(int playerId, int timeoutSec)
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ public:
|
|||||||
void SendJoinGame(unsigned gameId, const std::string &password);
|
void SendJoinGame(unsigned gameId, const std::string &password);
|
||||||
void SendCreateGame(const GameData &gameData, const std::string &name, const std::string &password);
|
void SendCreateGame(const GameData &gameData, const std::string &name, const std::string &password);
|
||||||
void SendResetTimeout();
|
void SendResetTimeout();
|
||||||
|
void SendAskKickPlayer(unsigned playerId);
|
||||||
|
|
||||||
GameInfo GetGameInfo(unsigned gameId) const;
|
GameInfo GetGameInfo(unsigned gameId) const;
|
||||||
PlayerInfo GetPlayerInfo(unsigned playerId) const;
|
PlayerInfo GetPlayerInfo(unsigned playerId) const;
|
||||||
|
|||||||
@@ -769,6 +769,12 @@ AbstractClientStateReceiving::Process(ClientThread &client)
|
|||||||
tmpPacket->ToNetPacketGameListAdminChanged()->GetData(adminChangedData);
|
tmpPacket->ToNetPacketGameListAdminChanged()->GetData(adminChangedData);
|
||||||
client.UpdateGameInfoAdmin(adminChangedData.gameId, adminChangedData.newAdminplayerId);
|
client.UpdateGameInfoAdmin(adminChangedData.gameId, adminChangedData.newAdminplayerId);
|
||||||
}
|
}
|
||||||
|
else if (tmpPacket->ToNetPacketStartKickPlayerPetition())
|
||||||
|
{
|
||||||
|
NetPacketStartKickPlayerPetition::Data petitionData;
|
||||||
|
tmpPacket->ToNetPacketStartKickPlayerPetition()->GetData(petitionData);
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
else if (tmpPacket->ToNetPacketAvatarHeader())
|
else if (tmpPacket->ToNetPacketAvatarHeader())
|
||||||
{
|
{
|
||||||
NetPacketAvatarHeader::Data headerData;
|
NetPacketAvatarHeader::Data headerData;
|
||||||
|
|||||||
@@ -253,6 +253,17 @@ ClientThread::SendResetTimeout()
|
|||||||
m_outPacketList.push_back(reset);
|
m_outPacketList.push_back(reset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ClientThread::SendAskKickPlayer(unsigned playerId)
|
||||||
|
{
|
||||||
|
boost::shared_ptr<NetPacket> ask(new NetPacketAskKickPlayer);
|
||||||
|
NetPacketAskKickPlayer::Data askData;
|
||||||
|
askData.playerId = playerId;
|
||||||
|
static_cast<NetPacketAskKickPlayer *>(ask.get())->SetData(askData);
|
||||||
|
boost::mutex::scoped_lock lock(m_outPacketListMutex);
|
||||||
|
m_outPacketList.push_back(ask);
|
||||||
|
}
|
||||||
|
|
||||||
GameInfo
|
GameInfo
|
||||||
ClientThread::GetGameInfo(unsigned gameId) const
|
ClientThread::GetGameInfo(unsigned gameId) const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ using namespace std;
|
|||||||
|
|
||||||
#define SERVER_GAME_ADMIN_WARNING_REMAINING_SEC 60
|
#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_GAME_ADMIN_TIMEOUT_SEC 300 // 5 min, MUST be > SERVER_GAME_ADMIN_WARNING_REMAINING_SEC
|
||||||
|
#define SERVER_VOTE_KICK_TIMEOUT_SEC 30
|
||||||
|
|
||||||
// Helper functions
|
// Helper functions
|
||||||
// TODO: these are hacks.
|
// TODO: these are hacks.
|
||||||
@@ -198,13 +199,24 @@ AbstractServerGameStateReceiving::Process(ServerGameThread &server)
|
|||||||
}
|
}
|
||||||
else if (packet->ToNetPacketAskKickPlayer())
|
else if (packet->ToNetPacketAskKickPlayer())
|
||||||
{
|
{
|
||||||
if (server.IsRunning())
|
if (server.IsRunning() && session.playerData)
|
||||||
{
|
{
|
||||||
NetPacketAskKickPlayer::Data askKickData;
|
NetPacketAskKickPlayer::Data askKickData;
|
||||||
packet->ToNetPacketAskKickPlayer()->GetData(askKickData);
|
packet->ToNetPacketAskKickPlayer()->GetData(askKickData);
|
||||||
|
|
||||||
// TODO start vote kick.
|
boost::shared_ptr<VoteKickData> voteData(server.InternalAskVoteKick(session.playerData->GetUniqueId(), askKickData.playerId));
|
||||||
//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->numVotesToKick;
|
||||||
|
static_cast<NetPacketStartKickPlayerPetition *>(startPetition.get())->SetData(startPetitionData);
|
||||||
|
server.GetSender().Send(session.sessionData, startPetition);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Chat text is always allowed.
|
// Chat text is always allowed.
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ using namespace std;
|
|||||||
ServerGameThread::ServerGameThread(ServerLobbyThread &lobbyThread, u_int32_t id, const string &name, const string &pwd, const GameData &gameData, unsigned adminPlayerId, GuiInterface &gui, ConfigFile *playerConfig)
|
ServerGameThread::ServerGameThread(ServerLobbyThread &lobbyThread, u_int32_t id, const string &name, const string &pwd, const GameData &gameData, unsigned adminPlayerId, GuiInterface &gui, ConfigFile *playerConfig)
|
||||||
: m_adminPlayerId(adminPlayerId), m_lobbyThread(lobbyThread), m_gui(gui),
|
: m_adminPlayerId(adminPlayerId), m_lobbyThread(lobbyThread), m_gui(gui),
|
||||||
m_gameData(gameData), m_id(id), m_name(name), m_password(pwd), m_playerConfig(playerConfig),
|
m_gameData(gameData), m_id(id), m_name(name), m_password(pwd), m_playerConfig(playerConfig),
|
||||||
m_curState(NULL), m_gameNum(1),
|
m_curState(NULL), m_gameNum(1), m_curPetitionId(1),
|
||||||
m_stateTimer(boost::posix_time::time_duration(0, 0, 0), boost::timers::portable::microsec_timer::manual_start),
|
m_stateTimer(boost::posix_time::time_duration(0, 0, 0), boost::timers::portable::microsec_timer::manual_start),
|
||||||
m_stateTimerFlag(0)
|
m_stateTimerFlag(0)
|
||||||
{
|
{
|
||||||
@@ -226,6 +226,27 @@ ServerGameThread::InternalKickPlayer(unsigned playerId)
|
|||||||
MoveSessionToLobby(tmpSession, NTF_NET_REMOVED_KICKED);
|
MoveSessionToLobby(tmpSession, NTF_NET_REMOVED_KICKED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boost::shared_ptr<VoteKickData>
|
||||||
|
ServerGameThread::InternalAskVoteKick(unsigned playerIdByWhom, unsigned playerIdWho)
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock lock(m_voteKickMapMutex);
|
||||||
|
// TODO: Check whether player is allowed to initiate vote.
|
||||||
|
// TODO: Check whether there are more than two players.
|
||||||
|
boost::shared_ptr<VoteKickData> voteData;
|
||||||
|
if (m_game)
|
||||||
|
{
|
||||||
|
voteData.reset(new VoteKickData);
|
||||||
|
voteData->petitionId = m_curPetitionId++;
|
||||||
|
voteData->kickPlayerId = playerIdWho;
|
||||||
|
voteData->numVotesToKick = static_cast<unsigned>(ceil(GetCurNumberOfPlayers() / 3. * 2.));
|
||||||
|
// Consider first vote.
|
||||||
|
voteData->numVotesToKick--;
|
||||||
|
voteData->votedPlayerIds.push_back(playerIdByWhom);
|
||||||
|
m_voteKickMap.insert(VoteKickMap::value_type(voteData->petitionId, voteData));
|
||||||
|
}
|
||||||
|
return voteData;
|
||||||
|
}
|
||||||
|
|
||||||
PlayerDataList
|
PlayerDataList
|
||||||
ServerGameThread::GetFullPlayerDataList() const
|
ServerGameThread::GetFullPlayerDataList() const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
|
|
||||||
typedef std::deque<SessionWrapper> SessionQueue;
|
typedef std::deque<SessionWrapper> SessionQueue;
|
||||||
|
typedef std::map<unsigned, boost::shared_ptr<VoteKickData> > VoteKickMap;
|
||||||
|
|
||||||
// Main function of the thread.
|
// Main function of the thread.
|
||||||
virtual void Main();
|
virtual void Main();
|
||||||
@@ -86,6 +87,7 @@ protected:
|
|||||||
void ResetGame();
|
void ResetGame();
|
||||||
|
|
||||||
void InternalKickPlayer(unsigned playerId);
|
void InternalKickPlayer(unsigned playerId);
|
||||||
|
boost::shared_ptr<VoteKickData> InternalAskVoteKick(unsigned playerIdByWhom, unsigned playerIdWho);
|
||||||
|
|
||||||
PlayerDataList GetFullPlayerDataList() const;
|
PlayerDataList GetFullPlayerDataList() const;
|
||||||
|
|
||||||
@@ -140,6 +142,9 @@ private:
|
|||||||
unsigned m_adminPlayerId;
|
unsigned m_adminPlayerId;
|
||||||
mutable boost::mutex m_adminPlayerIdMutex;
|
mutable boost::mutex m_adminPlayerIdMutex;
|
||||||
|
|
||||||
|
VoteKickMap m_voteKickMap;
|
||||||
|
mutable boost::mutex m_voteKickMapMutex;
|
||||||
|
|
||||||
ServerLobbyThread &m_lobbyThread;
|
ServerLobbyThread &m_lobbyThread;
|
||||||
boost::shared_ptr<ReceiverHelper> m_receiver;
|
boost::shared_ptr<ReceiverHelper> m_receiver;
|
||||||
GuiInterface &m_gui;
|
GuiInterface &m_gui;
|
||||||
@@ -153,6 +158,7 @@ private:
|
|||||||
ConfigFile *m_playerConfig;
|
ConfigFile *m_playerConfig;
|
||||||
ServerGameState *m_curState;
|
ServerGameState *m_curState;
|
||||||
unsigned m_gameNum;
|
unsigned m_gameNum;
|
||||||
|
unsigned m_curPetitionId;
|
||||||
|
|
||||||
boost::timers::portable::microsec_timer m_stateTimer;
|
boost::timers::portable::microsec_timer m_stateTimer;
|
||||||
unsigned m_stateTimerFlag;
|
unsigned m_stateTimerFlag;
|
||||||
|
|||||||
@@ -388,6 +388,13 @@ void Session::kickPlayer(const string &playerName)
|
|||||||
kickPlayer(playerId);
|
kickPlayer(playerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Session::startVoteKickPlayer(unsigned playerId)
|
||||||
|
{
|
||||||
|
if (!myNetClient)
|
||||||
|
return; // only act if client is running.
|
||||||
|
myNetClient->SendAskKickPlayer(playerId);
|
||||||
|
}
|
||||||
|
|
||||||
bool Session::isNetworkClientRunning() const
|
bool Session::isNetworkClientRunning() const
|
||||||
{
|
{
|
||||||
// This, and every place which calls this, is a HACK.
|
// This, and every place which calls this, is a HACK.
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ public:
|
|||||||
void sendChatMessage(const std::string &message);
|
void sendChatMessage(const std::string &message);
|
||||||
void kickPlayer(unsigned playerId);
|
void kickPlayer(unsigned playerId);
|
||||||
void kickPlayer(const std::string &playerName);
|
void kickPlayer(const std::string &playerName);
|
||||||
|
void startVoteKickPlayer(unsigned playerId);
|
||||||
|
|
||||||
void resetNetworkTimeout();
|
void resetNetworkTimeout();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user