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
|
// Anzahl noch aktiver Spieler ermitteln
|
||||||
actualQuantityPlayers = 0;
|
actualQuantityPlayers = 0;
|
||||||
for(i=0; i<MAX_NUMBER_OF_PLAYERS; i++) {
|
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
|
//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::SignalNetClientGameInfo(int actionID) { myW->signalNetClientGameInfo(actionID); }
|
||||||
void GuiWrapper::SignalNetClientError(int errorID, int osErrorID) { myW->signalNetClientError(errorID, osErrorID); }
|
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::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::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::SignalNetClientChatMsg(const string &playerName, const string &msg) { myChat->signalChatMessage(QString::fromUtf8(playerName.c_str()), QString::fromUtf8(msg.c_str())); }
|
||||||
void GuiWrapper::SignalNetClientWaitDialog() { myW->signalShowClientWaitDialog(); }
|
void GuiWrapper::SignalNetClientWaitDialog() { myW->signalShowClientWaitDialog(); }
|
||||||
@@ -116,11 +121,6 @@ void GuiWrapper::SignalNetClientWaitDialog() { myW->signalShowClientWaitDialog()
|
|||||||
void GuiWrapper::SignalNetServerSuccess(int actionID) { }
|
void GuiWrapper::SignalNetServerSuccess(int actionID) { }
|
||||||
void GuiWrapper::SignalNetServerError(int errorID, int osErrorID) { myW->signalNetServerError(errorID, osErrorID); }
|
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::SignalNetServerPlayerJoined(const string &playerName) { myW->signalNetServerPlayerJoined(QString::fromUtf8(playerName.c_str())); }
|
||||||
void GuiWrapper::SignalNetServerPlayerLeft(const string &playerName)
|
void GuiWrapper::SignalNetServerPlayerLeft(const string &playerName) { myW->signalNetServerPlayerLeft(QString::fromUtf8(playerName.c_str())); }
|
||||||
{
|
|
||||||
QString tmpName(QString::fromUtf8(playerName.c_str()));
|
|
||||||
myW->signalNetServerPlayerLeft(tmpName);
|
|
||||||
myLog->signalLogPlayerLeftMsg(tmpName);
|
|
||||||
}
|
|
||||||
void GuiWrapper::SignalNetServerStartDialog() { myW->signalShowServerStartDialog(); }
|
void GuiWrapper::SignalNetServerStartDialog() { myW->signalShowServerStartDialog(); }
|
||||||
|
|
||||||
|
|||||||
@@ -90,6 +90,8 @@ protected:
|
|||||||
const PlayerDataList &GetPlayerDataList() const;
|
const PlayerDataList &GetPlayerDataList() const;
|
||||||
boost::shared_ptr<PlayerData> GetPlayerDataByUniqueId(unsigned id);
|
boost::shared_ptr<PlayerData> GetPlayerDataByUniqueId(unsigned id);
|
||||||
|
|
||||||
|
void RemoveDisconnectedPlayers();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::auto_ptr<ClientContext> m_context;
|
std::auto_ptr<ClientContext> m_context;
|
||||||
|
|||||||
@@ -403,26 +403,8 @@ AbstractClientStateReceiving::Process(ClientThread &client)
|
|||||||
NetPacketPlayerLeft::Data playerLeftData;
|
NetPacketPlayerLeft::Data playerLeftData;
|
||||||
tmpPacket->ToNetPacketPlayerLeft()->GetData(playerLeftData);
|
tmpPacket->ToNetPacketPlayerLeft()->GetData(playerLeftData);
|
||||||
|
|
||||||
// Signal to GUI.
|
// Signal to GUI and remove from data list.
|
||||||
client.RemovePlayerData(playerLeftData.playerId);
|
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
|
else
|
||||||
retVal = InternalProcess(client, tmpPacket);
|
retVal = InternalProcess(client, tmpPacket);
|
||||||
@@ -551,6 +533,8 @@ ClientStateWaitHand::InternalProcess(ClientThread &client, boost::shared_ptr<Net
|
|||||||
|
|
||||||
if (packet->ToNetPacketHandStart())
|
if (packet->ToNetPacketHandStart())
|
||||||
{
|
{
|
||||||
|
// Remove all players which left the server.
|
||||||
|
client.RemoveDisconnectedPlayers();
|
||||||
// Hand was started.
|
// Hand was started.
|
||||||
// These are the cards. Good luck.
|
// These are the cards. Good luck.
|
||||||
NetPacketHandStart::Data tmpData;
|
NetPacketHandStart::Data tmpData;
|
||||||
|
|||||||
@@ -355,3 +355,25 @@ ClientThread::GetPlayerDataByUniqueId(unsigned id)
|
|||||||
return tmpPlayer;
|
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);
|
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.
|
// Start next hand - if enough players are left.
|
||||||
int playersPositiveCashCounter = 0;
|
int playersPositiveCashCounter = 0;
|
||||||
for (int i = 0; i < curGame.getStartQuantityPlayers(); i++)
|
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.
|
// If the player we are waiting for left, continue without him.
|
||||||
PlayerInterface *tmpPlayer = GetCurrentPlayer(server.GetGame());
|
PlayerInterface *tmpPlayer = GetCurrentPlayer(server.GetGame());
|
||||||
assert(tmpPlayer);
|
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);
|
PerformPlayerAction(server, tmpPlayer, PLAYER_ACTION_FOLD, 0);
|
||||||
|
|
||||||
server.SetState(ServerRecvStateStartRound::Instance());
|
server.SetState(ServerRecvStateStartRound::Instance());
|
||||||
|
|||||||
@@ -297,7 +297,7 @@ ServerRecvThread::InternalKickPlayer(const string playerName)
|
|||||||
{
|
{
|
||||||
if (!playerName.empty())
|
if (!playerName.empty())
|
||||||
{
|
{
|
||||||
SessionWrapper tmpSession = GetSession(playerName);
|
SessionWrapper tmpSession = GetSessionByPlayerName(playerName);
|
||||||
|
|
||||||
SessionError(tmpSession, ERR_NET_PLAYER_KICKED);
|
SessionError(tmpSession, ERR_NET_PLAYER_KICKED);
|
||||||
}
|
}
|
||||||
@@ -318,7 +318,7 @@ ServerRecvThread::GetSession(SOCKET sock) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
SessionWrapper
|
SessionWrapper
|
||||||
ServerRecvThread::GetSession(const string playerName) const
|
ServerRecvThread::GetSessionByPlayerName(const string playerName) const
|
||||||
{
|
{
|
||||||
SessionWrapper tmpSession;
|
SessionWrapper tmpSession;
|
||||||
boost::mutex::scoped_lock lock(m_sessionMapMutex);
|
boost::mutex::scoped_lock lock(m_sessionMapMutex);
|
||||||
@@ -345,6 +345,34 @@ ServerRecvThread::GetSession(const string playerName) const
|
|||||||
return tmpSession;
|
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
|
void
|
||||||
ServerRecvThread::AddSession(boost::shared_ptr<SessionData> sessionData)
|
ServerRecvThread::AddSession(boost::shared_ptr<SessionData> sessionData)
|
||||||
{
|
{
|
||||||
@@ -390,23 +418,6 @@ ServerRecvThread::CloseSessionDelayed(SessionWrapper session)
|
|||||||
boost::shared_ptr<PlayerData> tmpPlayerData = session.playerData;
|
boost::shared_ptr<PlayerData> tmpPlayerData = session.playerData;
|
||||||
if (tmpPlayerData.get() && !tmpPlayerData->GetName().empty())
|
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.
|
// Send "Player Left" to clients.
|
||||||
boost::shared_ptr<NetPacket> thisPlayerLeft(new NetPacketPlayerLeft);
|
boost::shared_ptr<NetPacket> thisPlayerLeft(new NetPacketPlayerLeft);
|
||||||
NetPacketPlayerLeft::Data thisPlayerLeftData;
|
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
|
size_t
|
||||||
ServerRecvThread::GetCurNumberOfPlayers() const
|
ServerRecvThread::GetCurNumberOfPlayers() const
|
||||||
{
|
{
|
||||||
@@ -468,7 +500,20 @@ ServerRecvThread::IsPlayerConnected(const string &playerName) const
|
|||||||
{
|
{
|
||||||
bool retVal = false;
|
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())
|
if (tmpSession.sessionData.get() && tmpSession.playerData.get())
|
||||||
retVal = true;
|
retVal = true;
|
||||||
|
|||||||
@@ -106,15 +106,18 @@ protected:
|
|||||||
void InternalKickPlayer(const std::string playerName);
|
void InternalKickPlayer(const std::string playerName);
|
||||||
|
|
||||||
SessionWrapper GetSession(SOCKET sock) const;
|
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 AddSession(boost::shared_ptr<SessionData> sessionData); // new Sessions have no player data
|
||||||
void SessionError(SessionWrapper session, int errorCode);
|
void SessionError(SessionWrapper session, int errorCode);
|
||||||
void RejectNewConnection(boost::shared_ptr<ConnectData> connData);
|
void RejectNewConnection(boost::shared_ptr<ConnectData> connData);
|
||||||
void CloseSessionDelayed(SessionWrapper session);
|
void CloseSessionDelayed(SessionWrapper session);
|
||||||
void RemoveNotEstablishedSessions();
|
void RemoveNotEstablishedSessions();
|
||||||
|
void RemoveDisconnectedPlayers();
|
||||||
|
|
||||||
size_t GetCurNumberOfPlayers() const;
|
size_t GetCurNumberOfPlayers() const;
|
||||||
bool IsPlayerConnected(const std::string &playerName) 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);
|
void SetSessionPlayerData(boost::shared_ptr<SessionData> sessionData, boost::shared_ptr<PlayerData> playerData);
|
||||||
PlayerDataList GetPlayerDataList() const;
|
PlayerDataList GetPlayerDataList() const;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user