Rewrote the code which handles leaving of players during the network game. Some bug is still remaining.

This commit is contained in:
lotodore
2007-06-15 10:38:41 +00:00
parent a7598a20eb
commit e19f6c7471
8 changed files with 110 additions and 50 deletions
+1 -1
View File
@@ -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
+7 -7
View File
@@ -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(); }
+2
View File
@@ -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;
+3 -19
View File
@@ -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;
+22
View File
@@ -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);
}
}
}
}
}
+6 -2
View File
@@ -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());
+65 -20
View File
@@ -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;
+4 -1
View File
@@ -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;