diff --git a/client/CServerHandler.cpp b/client/CServerHandler.cpp index fe48a0b14..ea4e24d19 100644 --- a/client/CServerHandler.cpp +++ b/client/CServerHandler.cpp @@ -140,6 +140,7 @@ void CServerHandler::resetStateForLobby(const StartInfo::EMode mode, const std:: { hostClientId = -1; state = EClientState::NONE; + mapToStart = nullptr; th = std::make_unique(); packsForLobbyScreen.clear(); c.reset(); @@ -396,6 +397,7 @@ void CServerHandler::sendClientDisconnecting() return; state = EClientState::DISCONNECTING; + mapToStart = nullptr; LobbyClientDisconnected lcd; lcd.clientId = c->connectionID; logNetwork->info("Connection has been requested to be closed."); @@ -553,6 +555,11 @@ void CServerHandler::sendStartGame(bool allowOnlyAI) const c->disableStackSendingByID(); } +void CServerHandler::startMapAfterConnection(std::shared_ptr to) +{ + mapToStart = to; +} + void CServerHandler::startGameplay(VCMI_LIB_WRAP_NAMESPACE(CGameState) * gameState) { if(CMM) diff --git a/client/CServerHandler.h b/client/CServerHandler.h index e8b20117d..7c1cfca46 100644 --- a/client/CServerHandler.h +++ b/client/CServerHandler.h @@ -74,10 +74,14 @@ public: /// structure to handle running server and connecting to it class CServerHandler : public IServerAPI, public LobbyInfo { + friend class ApplyOnLobbyHandlerNetPackVisitor; + std::shared_ptr> applier; std::shared_ptr mx; std::list packsForLobbyScreen; //protected by mx + + std::shared_ptr mapToStart; std::vector myNames; @@ -148,6 +152,7 @@ public: void sendRestartGame() const override; void sendStartGame(bool allowOnlyAI = false) const override; + void startMapAfterConnection(std::shared_ptr to); void startGameplay(VCMI_LIB_WRAP_NAMESPACE(CGameState) * gameState = nullptr); void endGameplay(bool closeConnection = true, bool restart = false); void startCampaignScenario(std::shared_ptr cs = {}); diff --git a/client/NetPacksLobbyClient.cpp b/client/NetPacksLobbyClient.cpp index 37ecb9788..8329e5e31 100644 --- a/client/NetPacksLobbyClient.cpp +++ b/client/NetPacksLobbyClient.cpp @@ -38,7 +38,9 @@ void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyClientConnected(LobbyClientCon if(pack.uuid == handler.c->uuid) { handler.c->connectionID = pack.clientId; - if(!settings["session"]["headless"].Bool()) + if(handler.mapToStart) + handler.setMapInfo(handler.mapToStart); + else if(!settings["session"]["headless"].Bool()) GH.windows().createAndPushWindow(static_cast(handler.screenType)); handler.state = EClientState::LOBBY; } @@ -136,6 +138,11 @@ void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyUpdateState(LobbyUpdateState & { pack.hostChanged = pack.state.hostClientId != handler.hostClientId; static_cast(handler) = pack.state; + if(handler.mapToStart && handler.mi) + { + handler.startMapAfterConnection(nullptr); + handler.sendStartGame(); + } } void ApplyOnLobbyScreenNetPackVisitor::visitLobbyUpdateState(LobbyUpdateState & pack) diff --git a/client/mainmenu/CMainMenu.cpp b/client/mainmenu/CMainMenu.cpp index e7501326b..c55ba614c 100644 --- a/client/mainmenu/CMainMenu.cpp +++ b/client/mainmenu/CMainMenu.cpp @@ -383,32 +383,8 @@ void CMainMenu::startTutorial() auto mapInfo = std::make_shared(); mapInfo->mapInit(tutorialMap.getName()); - + CSH->startMapAfterConnection(mapInfo); CMainMenu::openLobby(ESelectionScreen::newGame, true, nullptr, ELoadMode::NONE); - - std::thread waitForConnectionThread([mapInfo](){ - boost::this_thread::sleep(boost::posix_time::milliseconds(100)); //delay this thread - - //connecting to server - while(CSH->state != EClientState::LOBBY) - { - if(CSH->state == EClientState::CONNECTION_CANCELLED || CSH->state == EClientState::NONE) - return; - boost::this_thread::sleep(boost::posix_time::milliseconds(50)); - } - - //start game from main thread - GH.dispatchMainThread([mapInfo]() - { - while(!CSH->si || mapInfo->fileURI != CSH->si->mapname) - { - CSH->setMapInfo(mapInfo); - boost::this_thread::sleep(boost::posix_time::milliseconds(50)); - } - CSH->sendStartGame(); - }); - }); - waitForConnectionThread.detach(); } std::shared_ptr CMainMenu::create()