diff --git a/src/gui/qt/mainwindow/mainwindowimpl.cpp b/src/gui/qt/mainwindow/mainwindowimpl.cpp index f2fe0909..836670bd 100755 --- a/src/gui/qt/mainwindow/mainwindowimpl.cpp +++ b/src/gui/qt/mainwindow/mainwindowimpl.cpp @@ -761,8 +761,8 @@ void mainWindowImpl::callCreateNetworkGameDialog() { myStartNetworkGameDialog->setSession(&getSession()); myStartNetworkGameDialog->treeWidget->clear(); - myServerGuiInterface->getSession().startNetworkServer(gameData); - mySession->startNetworkClientForLocalServer(); + myServerGuiInterface->getSession().startNetworkServer(); + mySession->startNetworkClientForLocalServer(gameData); myStartNetworkGameDialog->setMaxPlayerNumber(gameData.maxNumberOfPlayers); @@ -821,8 +821,8 @@ void mainWindowImpl::callGameLobbyDialog() { myStartNetworkGameDialog->treeWidget->clear(); myStartNetworkGameDialog->setSession(&getSession()); - // Just for testing - mySession->startNetworkClientForLocalServer(); + // Start client for dedicated server. + mySession->startInternetClient(); myGameLobbyDialog->exec(); diff --git a/src/net/clientthread.h b/src/net/clientthread.h index 4ce2d99c..96216316 100644 --- a/src/net/clientthread.h +++ b/src/net/clientthread.h @@ -27,6 +27,7 @@ #include #include #include +#include class ClientContext; class ClientState; @@ -34,6 +35,7 @@ class SenderThread; class ReceiverHelper; class ClientSenderCallback; class Game; +class NetPacket; class ClientThread : public Thread { @@ -56,6 +58,7 @@ public: void SendStartEvent(); void SendPlayerAction(); void SendChatMessage(const std::string &msg); + void SendJoinFirstGame(const std::string &password); void SendJoinGame(const std::string &name, const std::string &password); void SendCreateGame(const GameData &gameData, const std::string &name, const std::string &password); @@ -64,10 +67,14 @@ public: protected: typedef std::map GameMap; + typedef std::list > NetPacketList; // Main function of the thread. virtual void Main(); + void AddPacket(boost::shared_ptr packet); + void SendPacketLoop(); + const ClientContext &GetContext() const; ClientContext &GetContext(); @@ -101,8 +108,14 @@ protected: void AddGameInformation(unsigned id, const std::string &name); void RemoveGameInformation(unsigned id); + bool IsSessionEstablished() const; + void SetSessionEstablished(bool flag); + private: + NetPacketList m_outPacketList; + mutable boost::mutex m_outPacketListMutex; + std::auto_ptr m_context; std::auto_ptr m_senderCallback; ClientState *m_curState; @@ -122,6 +135,7 @@ private: unsigned m_curGameId; unsigned m_guiPlayerId; + bool m_sessionEstablished; friend class AbstractClientStateReceiving; friend class ClientStateInit; diff --git a/src/net/common/clientstate.cpp b/src/net/common/clientstate.cpp index 6a1b1225..1189f740 100644 --- a/src/net/common/clientstate.cpp +++ b/src/net/common/clientstate.cpp @@ -442,6 +442,7 @@ ClientStateWaitSession::InternalProcess(ClientThread &client, boost::shared_ptr< client.SetGuiPlayerId(initAckData.playerId); client.SetState(ClientStateWaitJoin::Instance()); + client.SetSessionEstablished(true); retVal = MSG_SOCK_SESSION_DONE; } diff --git a/src/net/common/clientthread.cpp b/src/net/common/clientthread.cpp index bf842b3a..1eb685f8 100644 --- a/src/net/common/clientthread.cpp +++ b/src/net/common/clientthread.cpp @@ -53,7 +53,7 @@ private: ClientThread::ClientThread(GuiInterface &gui) -: m_curState(NULL), m_gui(gui), m_curGameId(1), m_guiPlayerId(0) +: m_curState(NULL), m_gui(gui), m_curGameId(1), m_guiPlayerId(0), m_sessionEstablished(false) { m_context.reset(new ClientContext); m_senderCallback.reset(new ClientSenderCallback(*this)); @@ -95,7 +95,8 @@ ClientThread::SendKickPlayer(const string &playerName) NetPacketKickPlayer::Data requestData; requestData.playerId = tmpPlayer->GetUniqueId(); static_cast(request.get())->SetData(requestData); - GetSender().Send(GetContext().GetSocket(), request); + boost::mutex::scoped_lock lock(m_outPacketListMutex); + m_outPacketList.push_back(request); } } @@ -105,8 +106,9 @@ ClientThread::SendStartEvent() // Warning: This function is called in the context of the GUI thread. // Create a network packet for the server start event. boost::shared_ptr startEvent(new NetPacketStartEvent); - // The sender is thread-safe, so just dump the packet. - GetSender().Send(GetContext().GetSocket(), startEvent); + // Just dump the packet. + boost::mutex::scoped_lock lock(m_outPacketListMutex); + m_outPacketList.push_back(startEvent); } void @@ -123,9 +125,15 @@ ClientThread::SendPlayerAction() actionData.playerBet = GetGame()->getPlayerArray()[0]->getMyLastRelativeSet(); else actionData.playerBet = 0; - static_cast(action.get())->SetData(actionData); - // The sender is thread-safe, so just dump the packet. - GetSender().Send(GetContext().GetSocket(), action); + try + { + static_cast(action.get())->SetData(actionData); + // Just dump the packet. + boost::mutex::scoped_lock lock(m_outPacketListMutex); + m_outPacketList.push_back(action); + } catch (const NetException &) + { + } } void @@ -139,13 +147,34 @@ ClientThread::SendChatMessage(const std::string &msg) try { static_cast(chat.get())->SetData(chatData); - // The sender is thread-safe, so just dump the packet. - GetSender().Send(GetContext().GetSocket(), chat); + // Just dump the packet. + boost::mutex::scoped_lock lock(m_outPacketListMutex); + m_outPacketList.push_back(chat); } catch (const NetException &) { } } +void +ClientThread::SendJoinFirstGame(const std::string &password) +{ + // Warning: This function is called in the context of the GUI thread. + // Create a network packet to request joining a game. + boost::shared_ptr join(new NetPacketJoinGame); + NetPacketJoinGame::Data joinData; + joinData.gameId = 0; + joinData.password = password; + try + { + static_cast(join.get())->SetData(joinData); + boost::mutex::scoped_lock lock(m_outPacketListMutex); + m_outPacketList.push_back(join); + } catch (const NetException &) + { + // TODO + } +} + void ClientThread::SendJoinGame(const std::string &name, const std::string &password) { @@ -158,7 +187,8 @@ ClientThread::SendJoinGame(const std::string &name, const std::string &password) { joinData.gameId = GetGameIdByName(name); static_cast(join.get())->SetData(joinData); - GetSender().Send(GetContext().GetSocket(), join); + boost::mutex::scoped_lock lock(m_outPacketListMutex); + m_outPacketList.push_back(join); } catch (const NetException &) { // TODO @@ -178,7 +208,8 @@ ClientThread::SendCreateGame(const GameData &gameData, const std::string &name, try { static_cast(create.get())->SetData(createData); - GetSender().Send(GetContext().GetSocket(), create); + boost::mutex::scoped_lock lock(m_outPacketListMutex); + m_outPacketList.push_back(create); } catch (const NetException &) { // TODO @@ -232,6 +263,8 @@ ClientThread::Main() GetCallback().SignalNetClientGameStart(m_game); } } + if (IsSessionEstablished()) + SendPacketLoop(); } } catch (const NetException &e) { @@ -241,6 +274,32 @@ ClientThread::Main() GetSender().Join(SENDER_THREAD_TERMINATE_TIMEOUT); } +void +ClientThread::AddPacket(boost::shared_ptr packet) +{ + boost::mutex::scoped_lock lock(m_outPacketListMutex); + m_outPacketList.push_back(packet); +} + +void +ClientThread::SendPacketLoop() +{ + boost::mutex::scoped_lock lock(m_outPacketListMutex); + + if (!m_outPacketList.empty()) + { + NetPacketList::iterator i = m_outPacketList.begin(); + NetPacketList::iterator end = m_outPacketList.end(); + + while (i != end) + { + GetSender().Send(GetContext().GetSocket(), *i); + ++i; + } + m_outPacketList.clear(); + } +} + const ClientContext & ClientThread::GetContext() const { @@ -520,3 +579,15 @@ ClientThread::RemoveGameInformation(unsigned id) GetCallback().SignalNetClientGameListRemove(name); } +bool +ClientThread::IsSessionEstablished() const +{ + return m_sessionEstablished; +} + +void +ClientThread::SetSessionEstablished(bool flag) +{ + m_sessionEstablished = flag; +} + diff --git a/src/pokerth_server.cpp b/src/pokerth_server.cpp index 2665e702..be3fc9b9 100644 --- a/src/pokerth_server.cpp +++ b/src/pokerth_server.cpp @@ -78,15 +78,7 @@ main(int argc, char *argv[]) myServerGuiInterface->setSession(session); } - GameData gameData; - gameData.maxNumberOfPlayers = myConfig->readConfigInt("NetNumberOfPlayers"); - gameData.startMoney = myConfig->readConfigInt("NetStartCash"); - gameData.smallBlind = myConfig->readConfigInt("NetSmallBlind"); - gameData.handsBeforeRaise = myConfig->readConfigInt("NetHandsBeforeRaiseSmallBlind"); - gameData.guiSpeed = 4; - gameData.playerActionTimeoutSec = myConfig->readConfigInt("NetTimeOutPlayerAction"); - - myServerGuiInterface->getSession().startNetworkServer(gameData); + myServerGuiInterface->getSession().startNetworkServer(); while (!g_pokerthTerminate) { myServerGuiInterface->getSession().waitForNetworkServer(100); diff --git a/src/session.cpp b/src/session.cpp index 559fd28a..f7219ce6 100755 --- a/src/session.cpp +++ b/src/session.cpp @@ -31,6 +31,8 @@ #define NET_CLIENT_TERMINATE_TIMEOUT_MSEC 1000 #define NET_SERVER_TERMINATE_TIMEOUT_MSEC 1000 +#define NET_DEFAULT_GAME "default" + using namespace std; Session::Session(GuiInterface *g, ConfigFile *c) @@ -105,6 +107,24 @@ GuiInterface *Session::getGui() return myGui; } +void Session::startInternetClient() +{ + if (myNetClient || !myGui) + { + assert(false); + return; + } + myNetClient = new ClientThread(*myGui); + myNetClient->Init( + myConfig->readConfigString("InternetServerAddress"), + myConfig->readConfigInt("InternetServerPort"), + myConfig->readConfigInt("InternetServerUseIpv6") == 1, + myConfig->readConfigInt("InternetServerUseSctp") == 1, + myConfig->readConfigString("InternetServerPassword"), + myConfig->readConfigString("MyName")); + myNetClient->Run(); +} + void Session::startNetworkClient(const string &serverAddress, unsigned serverPort, bool ipv6, bool sctp, const string &pwd) { if (myNetClient || !myGui) @@ -121,9 +141,10 @@ void Session::startNetworkClient(const string &serverAddress, unsigned serverPor pwd, myConfig->readConfigString("MyName")); myNetClient->Run(); + myNetClient->SendJoinFirstGame(""); } -void Session::startNetworkClientForLocalServer() +void Session::startNetworkClientForLocalServer(const GameData &gameData) { if (myNetClient || !myGui) { @@ -141,6 +162,7 @@ void Session::startNetworkClientForLocalServer() myConfig->readConfigString("ServerPassword"), myConfig->readConfigString("MyName")); myNetClient->Run(); + myNetClient->SendCreateGame(gameData, NET_DEFAULT_GAME, ""); } void Session::terminateNetworkClient() @@ -171,7 +193,7 @@ void Session::clientJoinGame(const std::string &name, const std::string &passwor myNetClient->SendJoinGame(name, password); } -void Session::startNetworkServer(const GameData &gameData) +void Session::startNetworkServer() { if (myNetServer) { diff --git a/src/session.h b/src/session.h index 23f4a446..bfc79667 100755 --- a/src/session.h +++ b/src/session.h @@ -45,13 +45,14 @@ public: GuiInterface *getGui(); + void startInternetClient(); void startNetworkClient(const std::string &serverAddress, unsigned serverPort, bool ipv6, bool sctp, const std::string &pwd); - void startNetworkClientForLocalServer(); + void startNetworkClientForLocalServer(const GameData &gameData); void terminateNetworkClient(); void clientCreateGame(const GameData &gameData, const std::string &name, const std::string &password); void clientJoinGame(const std::string &name, const std::string &password); - void startNetworkServer(const GameData &gameData); + void startNetworkServer(); void sendStartEvent(); void terminateNetworkServer(); void waitForNetworkServer(unsigned timeoutMsec);