More fixes. Using player name as base for game name now. Removing games which have no players left. Check collision of all player names on connect (kind of slow, but name needs to be unique).

This commit is contained in:
lotodore
2007-08-21 17:27:13 +00:00
parent 3e4b134faa
commit 3a2f3255af
10 changed files with 120 additions and 15 deletions
@@ -21,6 +21,9 @@ gameLobbyDialogImpl::gameLobbyDialogImpl(QWidget *parent, ConfigFile *c)
connect( pushButton_CreateGame, SIGNAL( clicked() ), this, SLOT( createGame() ) ); connect( pushButton_CreateGame, SIGNAL( clicked() ), this, SLOT( createGame() ) );
connect( pushButton_JoinGame, SIGNAL( clicked() ), this, SLOT( joinGame() ) ); connect( pushButton_JoinGame, SIGNAL( clicked() ), this, SLOT( joinGame() ) );
connect( treeWidget_GameList, SIGNAL( itemClicked ( QTreeWidgetItem*, int) ), this, SLOT( gameSelected(QTreeWidgetItem*, int) ) );
pushButton_JoinGame->setEnabled(false);
} }
void gameLobbyDialogImpl::exec() void gameLobbyDialogImpl::exec()
@@ -53,18 +56,28 @@ void gameLobbyDialogImpl::createGame()
//Speeds //Speeds
gameData.guiSpeed = myConfig->readConfigInt("GameSpeed"); gameData.guiSpeed = myConfig->readConfigInt("GameSpeed");
mySession->clientCreateGame(gameData, "default", ""); mySession->clientCreateGame(gameData, myConfig->readConfigString("MyName") + "'s game", "");
accept(); accept();
} }
void gameLobbyDialogImpl::joinGame() void gameLobbyDialogImpl::joinGame()
{ {
assert(mySession); QTreeWidgetItem *item = treeWidget_GameList->currentItem();
if (item)
{
QString gameName = item->text(0);
mySession->clientJoinGame("default", ""); assert(mySession);
mySession->clientJoinGame(gameName.toUtf8().constData(), "");
accept(); accept();
}
}
void gameLobbyDialogImpl::gameSelected(QTreeWidgetItem*, int)
{
pushButton_JoinGame->setEnabled(true);
} }
void gameLobbyDialogImpl::addGame(QString gameName) void gameLobbyDialogImpl::addGame(QString gameName)
@@ -39,6 +39,8 @@ public slots:
void createGame(); void createGame();
void joinGame(); void joinGame();
void gameSelected(QTreeWidgetItem*, int);
void addGame(QString gameName); void addGame(QString gameName);
void removeGame(QString gameName); void removeGame(QString gameName);
@@ -32,8 +32,8 @@ startNetworkGameDialogImpl::startNetworkGameDialogImpl(QWidget *parent, ConfigFi
connect( pushButton_Kick, SIGNAL( clicked() ), this, SLOT( kickPlayer() ) ); connect( pushButton_Kick, SIGNAL( clicked() ), this, SLOT( kickPlayer() ) );
connect( treeWidget, SIGNAL( itemClicked ( QTreeWidgetItem*, int) ), this, SLOT( playerSelected(QTreeWidgetItem*, int) ) ); connect( treeWidget, SIGNAL( itemClicked ( QTreeWidgetItem*, int) ), this, SLOT( playerSelected(QTreeWidgetItem*, int) ) );
pushButton_Kick->setEnabled(FALSE); pushButton_Kick->setEnabled(false);
pushButton_startGame->setEnabled(FALSE); pushButton_startGame->setEnabled(false);
} }
void startNetworkGameDialogImpl::startGame() { void startNetworkGameDialogImpl::startGame() {
+7 -3
View File
@@ -655,9 +655,13 @@ ServerGameStateStartRound::Process(ServerGameThread &server)
if (curGame.getCurrentHand()->getPlayerArray()[i]->getMyCash() > 0) if (curGame.getCurrentHand()->getPlayerArray()[i]->getMyCash() > 0)
playersPositiveCashCounter++; playersPositiveCashCounter++;
} }
// TODO: this is not an assert - terminate game if true. if (!playersPositiveCashCounter)
assert(playersPositiveCashCounter); {
if (playersPositiveCashCounter == 1) // No more players left - restart.
server.SetState(SERVER_INITIAL_STATE::Instance());
retVal = MSG_NET_GAME_SERVER_END;
}
else if (playersPositiveCashCounter == 1)
{ {
// View a dialog for a new game - delayed. // View a dialog for a new game - delayed.
server.SetState(ServerGameStateNextGameDelay::Instance()); server.SetState(ServerGameStateNextGameDelay::Instance());
+4 -2
View File
@@ -109,7 +109,7 @@ ServerGameThread::Main()
try try
{ {
while (!ShouldTerminate()) do
{ {
{ {
// Handle one new session at a time. // Handle one new session at a time.
@@ -127,13 +127,15 @@ ServerGameThread::Main()
} }
// Process current state. // Process current state.
GetState().Process(*this); GetState().Process(*this);
} } while (!ShouldTerminate() && GetSessionManager().HasSessions());
} catch (const NetException &e) } catch (const NetException &e)
{ {
GetCallback().SignalNetServerError(e.GetErrorId(), e.GetOsErrorCode()); GetCallback().SignalNetServerError(e.GetErrorId(), e.GetOsErrorCode());
} }
GetSender().SignalTermination(); GetSender().SignalTermination();
GetSender().Join(SENDER_THREAD_TERMINATE_TIMEOUT); GetSender().Join(SENDER_THREAD_TERMINATE_TIMEOUT);
GetLobbyThread().RemoveGame(GetId());
} }
void void
+66 -2
View File
@@ -93,6 +93,13 @@ ServerLobbyThread::CloseSessionDelayed(SessionWrapper session)
m_closeSessionList.push_back(closeSessionData); m_closeSessionList.push_back(closeSessionData);
} }
void
ServerLobbyThread::RemoveGame(unsigned id)
{
boost::mutex::scoped_lock lock(m_removeGameListMutex);
m_removeGameList.push_back(id);
}
u_int32_t u_int32_t
ServerLobbyThread::GetNextUniquePlayerId() ServerLobbyThread::GetNextUniquePlayerId()
{ {
@@ -132,6 +139,8 @@ ServerLobbyThread::Main()
ProcessLoop(); ProcessLoop();
// Close sessions. // Close sessions.
CloseSessionLoop(); CloseSessionLoop();
// Remove games.
RemoveGameLoop();
} }
} catch (const NetException &e) } catch (const NetException &e)
{ {
@@ -221,7 +230,7 @@ ServerLobbyThread::HandleNetPacketInit(SessionWrapper session, const NetPacketIn
} }
// Check whether this player is already connected. // Check whether this player is already connected.
if (m_sessionManager.IsPlayerConnected(initData.playerName)) if (IsPlayerConnected(initData.playerName))
{ {
SessionError(session, ERR_NET_PLAYER_NAME_IN_USE); SessionError(session, ERR_NET_PLAYER_NAME_IN_USE);
return; return;
@@ -289,7 +298,6 @@ ServerLobbyThread::HandleNetPacketJoinGame(SessionWrapper session, const NetPack
GameMap::iterator pos = m_gameMap.find(joinGameData.gameId); GameMap::iterator pos = m_gameMap.find(joinGameData.gameId);
// TODO: handle errors
if (pos != m_gameMap.end()) if (pos != m_gameMap.end())
{ {
ServerGameThread &game = *pos->second; ServerGameThread &game = *pos->second;
@@ -300,6 +308,14 @@ ServerLobbyThread::HandleNetPacketJoinGame(SessionWrapper session, const NetPack
// Add session to the game. // Add session to the game.
game.AddSession(session); game.AddSession(session);
} }
else
{
SessionError(session, ERR_NET_INVALID_PASSWORD);
}
}
else
{
SessionError(session, ERR_NET_UNKNOWN_GAME);
} }
} }
@@ -320,6 +336,30 @@ ServerLobbyThread::CloseSessionLoop()
} }
} }
void
ServerLobbyThread::RemoveGameLoop()
{
boost::mutex::scoped_lock lock(m_removeGameListMutex);
RemoveGameList::iterator i = m_removeGameList.begin();
RemoveGameList::iterator end = m_removeGameList.end();
// Synchronously remove games which have been closed.
while (i != end)
{
GameMap::iterator pos = m_gameMap.find(*i);
if (pos != m_gameMap.end())
{
boost::shared_ptr<ServerGameThread> tmpGame = pos->second;
tmpGame->SignalTermination();
tmpGame->Join(GAME_THREAD_TERMINATE_TIMEOUT);
m_gameMap.erase(pos);
}
++i;
}
m_removeGameList.clear();
}
void void
ServerLobbyThread::TerminateGames() ServerLobbyThread::TerminateGames()
{ {
@@ -427,6 +467,30 @@ ServerLobbyThread::GetGui()
return m_gui; return m_gui;
} }
bool
ServerLobbyThread::IsPlayerConnected(const string &name)
{
bool retVal = false;
retVal = m_sessionManager.IsPlayerConnected(name);
if (!retVal)
{
GameMap::const_iterator game_i = m_gameMap.begin();
GameMap::const_iterator game_end = m_gameMap.end();
while (game_i != game_end)
{
if (game_i->second->GetSessionManager().IsPlayerConnected(name))
{
retVal = true;
break;
}
++game_i;
}
}
return retVal;
}
boost::shared_ptr<NetPacket> boost::shared_ptr<NetPacket>
ServerLobbyThread::CreateNetPacketGameListNew(const ServerGameThread &game) ServerLobbyThread::CreateNetPacketGameListNew(const ServerGameThread &game)
{ {
+7
View File
@@ -34,6 +34,13 @@ SessionManager::~SessionManager()
Clear(); Clear();
} }
bool
SessionManager::HasSessions() const
{
boost::mutex::scoped_lock lock(m_sessionMapMutex);
return !m_sessionMap.empty();
}
void void
SessionManager::AddSession(boost::shared_ptr<SessionData> sessionData) SessionManager::AddSession(boost::shared_ptr<SessionData> sessionData)
{ {
+3 -2
View File
@@ -60,6 +60,9 @@ public:
bool CheckPassword(const std::string &password) const; bool CheckPassword(const std::string &password) const;
const GameData &GetGameData() const; const GameData &GetGameData() const;
const SessionManager &GetSessionManager() const;
SessionManager &GetSessionManager();
protected: protected:
typedef std::deque<SessionWrapper> SessionQueue; typedef std::deque<SessionWrapper> SessionQueue;
@@ -82,8 +85,6 @@ protected:
size_t GetCurNumberOfPlayers() const; size_t GetCurNumberOfPlayers() const;
void AssignPlayerNumbers(); void AssignPlayerNumbers();
SessionManager &GetSessionManager();
const SessionManager &GetSessionManager() const;
ServerLobbyThread &GetLobbyThread(); ServerLobbyThread &GetLobbyThread();
ServerGameState &GetState(); ServerGameState &GetState();
+10
View File
@@ -53,6 +53,8 @@ public:
void AddConnection(boost::shared_ptr<ConnectData> data); void AddConnection(boost::shared_ptr<ConnectData> data);
void CloseSessionDelayed(SessionWrapper session); void CloseSessionDelayed(SessionWrapper session);
void RemoveGame(unsigned id);
u_int32_t GetNextUniquePlayerId(); u_int32_t GetNextUniquePlayerId();
u_int32_t GetNextGameId(); u_int32_t GetNextGameId();
ServerCallback &GetCallback(); ServerCallback &GetCallback();
@@ -63,6 +65,7 @@ protected:
typedef std::list<SessionWrapper> SessionList; typedef std::list<SessionWrapper> SessionList;
typedef std::list<std::pair<boost::microsec_timer, boost::shared_ptr<SessionData> > > CloseSessionList; typedef std::list<std::pair<boost::microsec_timer, boost::shared_ptr<SessionData> > > CloseSessionList;
typedef std::map<unsigned, boost::shared_ptr<ServerGameThread> > GameMap; typedef std::map<unsigned, boost::shared_ptr<ServerGameThread> > GameMap;
typedef std::list<unsigned> RemoveGameList;
// Main function of the thread. // Main function of the thread.
virtual void Main(); virtual void Main();
@@ -72,6 +75,8 @@ protected:
void HandleNetPacketCreateGame(SessionWrapper session, const NetPacketCreateGame &tmpPacket); void HandleNetPacketCreateGame(SessionWrapper session, const NetPacketCreateGame &tmpPacket);
void HandleNetPacketJoinGame(SessionWrapper session, const NetPacketJoinGame &tmpPacket); void HandleNetPacketJoinGame(SessionWrapper session, const NetPacketJoinGame &tmpPacket);
void CloseSessionLoop(); void CloseSessionLoop();
void RemoveGameLoop();
void TerminateGames(); void TerminateGames();
void HandleNewConnection(boost::shared_ptr<ConnectData> connData); void HandleNewConnection(boost::shared_ptr<ConnectData> connData);
@@ -92,6 +97,8 @@ protected:
ServerSenderCallback &GetSenderCallback(); ServerSenderCallback &GetSenderCallback();
GuiInterface &GetGui(); GuiInterface &GetGui();
bool IsPlayerConnected(const std::string &name);
static boost::shared_ptr<NetPacket> CreateNetPacketGameListNew(const ServerGameThread &game); static boost::shared_ptr<NetPacket> CreateNetPacketGameListNew(const ServerGameThread &game);
private: private:
@@ -104,6 +111,9 @@ private:
CloseSessionList m_closeSessionList; CloseSessionList m_closeSessionList;
mutable boost::mutex m_closeSessionListMutex; mutable boost::mutex m_closeSessionListMutex;
RemoveGameList m_removeGameList;
mutable boost::mutex m_removeGameListMutex;
GameMap m_gameMap; GameMap m_gameMap;
std::auto_ptr<ReceiverHelper> m_receiver; std::auto_ptr<ReceiverHelper> m_receiver;
+2
View File
@@ -46,6 +46,8 @@ public:
SessionManager(); SessionManager();
virtual ~SessionManager(); virtual ~SessionManager();
bool HasSessions() const;
void AddSession(boost::shared_ptr<SessionData> sessionData); // new Sessions without player data void AddSession(boost::shared_ptr<SessionData> sessionData); // new Sessions without player data
void AddSession(SessionWrapper session); void AddSession(SessionWrapper session);
void SetSessionPlayerData(SOCKET session, boost::shared_ptr<PlayerData> playerData); void SetSessionPlayerData(SOCKET session, boost::shared_ptr<PlayerData> playerData);