Rewrote the code which handles leaving of players during the network game. Some bug is still remaining.
This commit is contained in:
+1
-1
@@ -148,7 +148,7 @@ void Game::initHand()
|
||||
// Anzahl noch aktiver Spieler ermitteln
|
||||
actualQuantityPlayers = 0;
|
||||
for(i=0; i<MAX_NUMBER_OF_PLAYERS; i++) {
|
||||
if(playerArray[i]->getMyActiveStatus() != 0) actualQuantityPlayers++;
|
||||
if(playerArray[i]->getMyActiveStatus()) actualQuantityPlayers++;
|
||||
}
|
||||
|
||||
//Spieler Action auf 0 setzen
|
||||
|
||||
@@ -108,7 +108,12 @@ void GuiWrapper::SignalNetClientConnect(int actionID) { myW->signalNetClientConn
|
||||
void GuiWrapper::SignalNetClientGameInfo(int actionID) { myW->signalNetClientGameInfo(actionID); }
|
||||
void GuiWrapper::SignalNetClientError(int errorID, int osErrorID) { myW->signalNetClientError(errorID, osErrorID); }
|
||||
void GuiWrapper::SignalNetClientPlayerJoined(const string &playerName) { myW->signalNetClientPlayerJoined(QString::fromUtf8(playerName.c_str())); }
|
||||
void GuiWrapper::SignalNetClientPlayerLeft(const string &playerName) { myW->signalNetClientPlayerLeft(QString::fromUtf8(playerName.c_str())); }
|
||||
void GuiWrapper::SignalNetClientPlayerLeft(const string &playerName)
|
||||
{
|
||||
QString tmpName(QString::fromUtf8(playerName.c_str()));
|
||||
myW->signalNetClientPlayerLeft(tmpName);
|
||||
myLog->signalLogPlayerLeftMsg(tmpName);
|
||||
}
|
||||
void GuiWrapper::SignalNetClientGameStart(boost::shared_ptr<Game> game) { myW->signalNetClientGameStart(game); }
|
||||
void GuiWrapper::SignalNetClientChatMsg(const string &playerName, const string &msg) { myChat->signalChatMessage(QString::fromUtf8(playerName.c_str()), QString::fromUtf8(msg.c_str())); }
|
||||
void GuiWrapper::SignalNetClientWaitDialog() { myW->signalShowClientWaitDialog(); }
|
||||
@@ -116,11 +121,6 @@ void GuiWrapper::SignalNetClientWaitDialog() { myW->signalShowClientWaitDialog()
|
||||
void GuiWrapper::SignalNetServerSuccess(int actionID) { }
|
||||
void GuiWrapper::SignalNetServerError(int errorID, int osErrorID) { myW->signalNetServerError(errorID, osErrorID); }
|
||||
void GuiWrapper::SignalNetServerPlayerJoined(const string &playerName) { myW->signalNetServerPlayerJoined(QString::fromUtf8(playerName.c_str())); }
|
||||
void GuiWrapper::SignalNetServerPlayerLeft(const string &playerName)
|
||||
{
|
||||
QString tmpName(QString::fromUtf8(playerName.c_str()));
|
||||
myW->signalNetServerPlayerLeft(tmpName);
|
||||
myLog->signalLogPlayerLeftMsg(tmpName);
|
||||
}
|
||||
void GuiWrapper::SignalNetServerPlayerLeft(const string &playerName) { myW->signalNetServerPlayerLeft(QString::fromUtf8(playerName.c_str())); }
|
||||
void GuiWrapper::SignalNetServerStartDialog() { myW->signalShowServerStartDialog(); }
|
||||
|
||||
|
||||
@@ -90,6 +90,8 @@ protected:
|
||||
const PlayerDataList &GetPlayerDataList() const;
|
||||
boost::shared_ptr<PlayerData> GetPlayerDataByUniqueId(unsigned id);
|
||||
|
||||
void RemoveDisconnectedPlayers();
|
||||
|
||||
private:
|
||||
|
||||
std::auto_ptr<ClientContext> m_context;
|
||||
|
||||
@@ -403,26 +403,8 @@ AbstractClientStateReceiving::Process(ClientThread &client)
|
||||
NetPacketPlayerLeft::Data playerLeftData;
|
||||
tmpPacket->ToNetPacketPlayerLeft()->GetData(playerLeftData);
|
||||
|
||||
// Signal to GUI.
|
||||
// Signal to GUI and remove from data list.
|
||||
client.RemovePlayerData(playerLeftData.playerId);
|
||||
|
||||
// If the game is running, deactivate player.
|
||||
boost::shared_ptr<Game> curGame = client.GetGame();
|
||||
if (curGame.get())
|
||||
{
|
||||
PlayerInterface *tmpPlayer = curGame->getPlayerByUniqueId(playerLeftData.playerId);
|
||||
if (!tmpPlayer)
|
||||
throw ClientException(ERR_NET_UNKNOWN_PLAYER_ID, 0);
|
||||
|
||||
// Reset his action and his cash.
|
||||
tmpPlayer->setMyAction(PLAYER_ACTION_FOLD);
|
||||
tmpPlayer->setMyCash(0);
|
||||
// Player is now inactive.
|
||||
tmpPlayer->setMyActiveStatus(false);
|
||||
|
||||
client.GetGui().refreshAction();
|
||||
client.GetGui().refreshCash();
|
||||
}
|
||||
}
|
||||
else
|
||||
retVal = InternalProcess(client, tmpPacket);
|
||||
@@ -551,6 +533,8 @@ ClientStateWaitHand::InternalProcess(ClientThread &client, boost::shared_ptr<Net
|
||||
|
||||
if (packet->ToNetPacketHandStart())
|
||||
{
|
||||
// Remove all players which left the server.
|
||||
client.RemoveDisconnectedPlayers();
|
||||
// Hand was started.
|
||||
// These are the cards. Good luck.
|
||||
NetPacketHandStart::Data tmpData;
|
||||
|
||||
@@ -355,3 +355,25 @@ ClientThread::GetPlayerDataByUniqueId(unsigned id)
|
||||
return tmpPlayer;
|
||||
}
|
||||
|
||||
void
|
||||
ClientThread::RemoveDisconnectedPlayers()
|
||||
{
|
||||
// This should only be called between hands.
|
||||
if (m_game.get())
|
||||
{
|
||||
for (int i = 0; i < m_game->getStartQuantityPlayers(); i++)
|
||||
{
|
||||
PlayerInterface *tmpPlayer = m_game->getPlayerArray()[i];
|
||||
if (tmpPlayer->getMyActiveStatus())
|
||||
{
|
||||
// If a player is not in the player data list, it was disconnected.
|
||||
if (!GetPlayerDataByUniqueId(tmpPlayer->getMyUniqueID()).get())
|
||||
{
|
||||
tmpPlayer->setMyCash(0);
|
||||
tmpPlayer->setMyActiveStatus(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -637,6 +637,10 @@ ServerRecvStateStartRound::Process(ServerRecvThread &server)
|
||||
|
||||
server.SendToAllPlayers(endHand);
|
||||
}
|
||||
|
||||
// Remove disconnected players. This is the one and only place to do this.
|
||||
server.RemoveDisconnectedPlayers();
|
||||
|
||||
// Start next hand - if enough players are left.
|
||||
int playersPositiveCashCounter = 0;
|
||||
for (int i = 0; i < curGame.getStartQuantityPlayers(); i++)
|
||||
@@ -728,9 +732,9 @@ ServerRecvStateWaitPlayerAction::Process(ServerRecvThread &server)
|
||||
// If the player we are waiting for left, continue without him.
|
||||
PlayerInterface *tmpPlayer = GetCurrentPlayer(server.GetGame());
|
||||
assert(tmpPlayer);
|
||||
if (!tmpPlayer->getMyActiveStatus())
|
||||
assert(!tmpPlayer->getMyName().empty());
|
||||
if (!server.IsPlayerConnected(tmpPlayer->getMyName()))
|
||||
{
|
||||
assert(tmpPlayer->getMyAction() == PLAYER_ACTION_FOLD && tmpPlayer->getMyCash() == 0);
|
||||
PerformPlayerAction(server, tmpPlayer, PLAYER_ACTION_FOLD, 0);
|
||||
|
||||
server.SetState(ServerRecvStateStartRound::Instance());
|
||||
|
||||
@@ -297,7 +297,7 @@ ServerRecvThread::InternalKickPlayer(const string playerName)
|
||||
{
|
||||
if (!playerName.empty())
|
||||
{
|
||||
SessionWrapper tmpSession = GetSession(playerName);
|
||||
SessionWrapper tmpSession = GetSessionByPlayerName(playerName);
|
||||
|
||||
SessionError(tmpSession, ERR_NET_PLAYER_KICKED);
|
||||
}
|
||||
@@ -318,7 +318,7 @@ ServerRecvThread::GetSession(SOCKET sock) const
|
||||
}
|
||||
|
||||
SessionWrapper
|
||||
ServerRecvThread::GetSession(const string playerName) const
|
||||
ServerRecvThread::GetSessionByPlayerName(const string playerName) const
|
||||
{
|
||||
SessionWrapper tmpSession;
|
||||
boost::mutex::scoped_lock lock(m_sessionMapMutex);
|
||||
@@ -345,6 +345,34 @@ ServerRecvThread::GetSession(const string playerName) const
|
||||
return tmpSession;
|
||||
}
|
||||
|
||||
SessionWrapper
|
||||
ServerRecvThread::GetSessionByUniquePlayerId(unsigned uniqueId) const
|
||||
{
|
||||
SessionWrapper tmpSession;
|
||||
boost::mutex::scoped_lock lock(m_sessionMapMutex);
|
||||
|
||||
SocketSessionMap::const_iterator session_i = m_sessionMap.begin();
|
||||
SocketSessionMap::const_iterator session_end = m_sessionMap.end();
|
||||
|
||||
while (session_i != session_end)
|
||||
{
|
||||
// Check all players which are fully connected.
|
||||
if (session_i->second.sessionData->GetState() == SessionData::Established)
|
||||
{
|
||||
boost::shared_ptr<PlayerData> tmpPlayer(session_i->second.playerData);
|
||||
assert(tmpPlayer.get());
|
||||
if (tmpPlayer->GetUniqueId() == uniqueId)
|
||||
{
|
||||
tmpSession = session_i->second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
++session_i;
|
||||
}
|
||||
return tmpSession;
|
||||
}
|
||||
|
||||
void
|
||||
ServerRecvThread::AddSession(boost::shared_ptr<SessionData> sessionData)
|
||||
{
|
||||
@@ -390,23 +418,6 @@ ServerRecvThread::CloseSessionDelayed(SessionWrapper session)
|
||||
boost::shared_ptr<PlayerData> tmpPlayerData = session.playerData;
|
||||
if (tmpPlayerData.get() && !tmpPlayerData->GetName().empty())
|
||||
{
|
||||
// Set player inactive.
|
||||
if (m_game.get())
|
||||
{
|
||||
PlayerInterface *player = GetGame().getPlayerByUniqueId(tmpPlayerData->GetUniqueId());
|
||||
if (player)
|
||||
{
|
||||
// Deactivate player (if active).
|
||||
if (player->getMyActiveStatus())
|
||||
{
|
||||
if (player->getMyAction() != PLAYER_ACTION_FOLD)
|
||||
player->setMyAction(PLAYER_ACTION_FOLD);
|
||||
player->setMyCash(0);
|
||||
player->setMyActiveStatus(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Send "Player Left" to clients.
|
||||
boost::shared_ptr<NetPacket> thisPlayerLeft(new NetPacketPlayerLeft);
|
||||
NetPacketPlayerLeft::Data thisPlayerLeftData;
|
||||
@@ -456,6 +467,27 @@ ServerRecvThread::RemoveNotEstablishedSessions()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ServerRecvThread::RemoveDisconnectedPlayers()
|
||||
{
|
||||
// This should only be called between hands.
|
||||
if (m_game.get())
|
||||
{
|
||||
for (int i = 0; i < m_game->getStartQuantityPlayers(); i++)
|
||||
{
|
||||
PlayerInterface *tmpPlayer = m_game->getPlayerArray()[i];
|
||||
if (tmpPlayer->getMyActiveStatus())
|
||||
{
|
||||
if (!IsPlayerConnected(tmpPlayer->getMyUniqueID()))
|
||||
{
|
||||
tmpPlayer->setMyCash(0);
|
||||
tmpPlayer->setMyActiveStatus(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
ServerRecvThread::GetCurNumberOfPlayers() const
|
||||
{
|
||||
@@ -468,7 +500,20 @@ ServerRecvThread::IsPlayerConnected(const string &playerName) const
|
||||
{
|
||||
bool retVal = false;
|
||||
|
||||
SessionWrapper tmpSession = GetSession(playerName);
|
||||
SessionWrapper tmpSession = GetSessionByPlayerName(playerName);
|
||||
|
||||
if (tmpSession.sessionData.get() && tmpSession.playerData.get())
|
||||
retVal = true;
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
bool
|
||||
ServerRecvThread::IsPlayerConnected(unsigned uniquePlayerId) const
|
||||
{
|
||||
bool retVal = false;
|
||||
|
||||
SessionWrapper tmpSession = GetSessionByUniquePlayerId(uniquePlayerId);
|
||||
|
||||
if (tmpSession.sessionData.get() && tmpSession.playerData.get())
|
||||
retVal = true;
|
||||
|
||||
@@ -106,15 +106,18 @@ protected:
|
||||
void InternalKickPlayer(const std::string playerName);
|
||||
|
||||
SessionWrapper GetSession(SOCKET sock) const;
|
||||
SessionWrapper GetSession(const std::string playerName) const;
|
||||
SessionWrapper GetSessionByPlayerName(const std::string playerName) const;
|
||||
SessionWrapper GetSessionByUniquePlayerId(unsigned uniqueId) const;
|
||||
void AddSession(boost::shared_ptr<SessionData> sessionData); // new Sessions have no player data
|
||||
void SessionError(SessionWrapper session, int errorCode);
|
||||
void RejectNewConnection(boost::shared_ptr<ConnectData> connData);
|
||||
void CloseSessionDelayed(SessionWrapper session);
|
||||
void RemoveNotEstablishedSessions();
|
||||
void RemoveDisconnectedPlayers();
|
||||
|
||||
size_t GetCurNumberOfPlayers() const;
|
||||
bool IsPlayerConnected(const std::string &playerName) const;
|
||||
bool IsPlayerConnected(unsigned uniquePlayerId) const;
|
||||
void SetSessionPlayerData(boost::shared_ptr<SessionData> sessionData, boost::shared_ptr<PlayerData> playerData);
|
||||
PlayerDataList GetPlayerDataList() const;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user