From fea05a43202e044776da91323fed4fdb3b1878f3 Mon Sep 17 00:00:00 2001 From: nordsoft Date: Thu, 29 Sep 2022 21:08:05 +0400 Subject: [PATCH] Finally game restart works # Conflicts: # lib/CGameState.cpp # server/CVCMIServer.cpp --- client/CMT.cpp | 2 +- client/CServerHandler.cpp | 11 +++++++++++ client/CServerHandler.h | 2 ++ client/NetPacksLobbyClient.cpp | 13 +++++++++++-- lib/NetPacksLobby.h | 16 ++++++++++++++++ lib/registerTypes/RegisterTypes.h | 1 + server/CVCMIServer.cpp | 7 ++++++- server/CVCMIServer.h | 1 + server/NetPacksLobbyServer.cpp | 21 +++++++++++++++++++++ 9 files changed, 70 insertions(+), 4 deletions(-) diff --git a/client/CMT.cpp b/client/CMT.cpp index 9a9139085..1e4c3f5b8 100644 --- a/client/CMT.cpp +++ b/client/CMT.cpp @@ -1359,7 +1359,7 @@ static void handleEvent(SDL_Event & ev) break; case EUserEvent::RESTART_GAME: { - CSH->sendStartGame(); + CSH->sendRestartGame(); } break; case EUserEvent::CAMPAIGN_START_SCENARIO: diff --git a/client/CServerHandler.cpp b/client/CServerHandler.cpp index a51dedc00..f76e6cac4 100644 --- a/client/CServerHandler.cpp +++ b/client/CServerHandler.cpp @@ -502,6 +502,14 @@ void CServerHandler::sendGuiAction(ui8 action) const sendLobbyPack(lga); } +void CServerHandler::sendRestartGame() const +{ + LobbyEndGame endGame; + endGame.closeConnection = false; + endGame.restart = true; + sendLobbyPack(endGame); +} + void CServerHandler::sendStartGame(bool allowOnlyAI) const { verifyStateBeforeStart(allowOnlyAI ? true : settings["session"]["onlyai"].Bool()); @@ -568,6 +576,9 @@ void CServerHandler::endGameplay(bool closeConnection, bool restart) GH.curInt = CMainMenu::create().get(); } } + + serverConnection->enterLobbyConnectionMode(); + serverConnection->disableStackSendingByID(); } void CServerHandler::startCampaignScenario(std::shared_ptr cs) diff --git a/client/CServerHandler.h b/client/CServerHandler.h index 4306161f7..ee850e53b 100644 --- a/client/CServerHandler.h +++ b/client/CServerHandler.h @@ -70,6 +70,7 @@ public: virtual void sendMessage(const std::string & txt) const = 0; virtual void sendGuiAction(ui8 action) const = 0; // TODO: possibly get rid of it? virtual void sendStartGame(bool allowOnlyAI = false) const = 0; + virtual void sendRestartGame() const = 0; }; /// structure to handle running server and connecting to it @@ -141,6 +142,7 @@ public: void setTurnLength(int npos) const override; void sendMessage(const std::string & txt) const override; void sendGuiAction(ui8 action) const override; + void sendRestartGame() const override; void sendStartGame(bool allowOnlyAI = false) const override; void startGameplay(CGameState * gameState = nullptr); diff --git a/client/NetPacksLobbyClient.cpp b/client/NetPacksLobbyClient.cpp index 656670a18..4e758682a 100644 --- a/client/NetPacksLobbyClient.cpp +++ b/client/NetPacksLobbyClient.cpp @@ -93,12 +93,21 @@ void LobbyGuiAction::applyOnLobbyScreen(CLobbyScreen * lobby, CServerHandler * h } } -bool LobbyStartGame::applyOnLobbyHandler(CServerHandler * handler) +bool LobbyEndGame::applyOnLobbyHandler(CServerHandler * handler) { if(handler->state == EClientState::GAMEPLAY) { - handler->endGameplay(false, true); + handler->endGameplay(closeConnection, restart); } + + if(restart) + handler->sendStartGame(); + + return true; +} + +bool LobbyStartGame::applyOnLobbyHandler(CServerHandler * handler) +{ handler->state = EClientState::STARTING; if(handler->si->mode != StartInfo::LOAD_GAME) { diff --git a/lib/NetPacksLobby.h b/lib/NetPacksLobby.h index d03c473c6..b4d8c95b5 100644 --- a/lib/NetPacksLobby.h +++ b/lib/NetPacksLobby.h @@ -138,6 +138,22 @@ struct LobbyGuiAction : public CLobbyPackToPropagate } }; +struct LobbyEndGame : public CLobbyPackToPropagate +{ + bool closeConnection = false, restart = false; + + bool checkClientPermissions(CVCMIServer * srv) const; + bool applyOnServer(CVCMIServer * srv); + void applyOnServerAfterAnnounce(CVCMIServer * srv); + bool applyOnLobbyHandler(CServerHandler * handler); + + template void serialize(Handler &h, const int version) + { + h & closeConnection; + h & restart; + } +}; + struct LobbyStartGame : public CLobbyPackToPropagate { // Set by server diff --git a/lib/registerTypes/RegisterTypes.h b/lib/registerTypes/RegisterTypes.h index 1e068c8ca..e73740b80 100644 --- a/lib/registerTypes/RegisterTypes.h +++ b/lib/registerTypes/RegisterTypes.h @@ -372,6 +372,7 @@ void registerTypesLobbyPacks(Serializer &s) s.template registerType(); // Only host client send s.template registerType(); + s.template registerType(); s.template registerType(); s.template registerType(); // Only server send diff --git a/server/CVCMIServer.cpp b/server/CVCMIServer.cpp index ec9f03be9..81307ebc8 100644 --- a/server/CVCMIServer.cpp +++ b/server/CVCMIServer.cpp @@ -220,7 +220,7 @@ void CVCMIServer::threadAnnounceLobby() } } -bool CVCMIServer::prepareToStartGame() +void CVCMIServer::prepareToRestart() { if(state == EServerState::GAMEPLAY) { @@ -237,7 +237,12 @@ bool CVCMIServer::prepareToStartGame() c->enterLobbyConnectionMode(); c->disableStackSendingByID(); } + boost::unique_lock queueLock(mx); + gh = nullptr; +} +bool CVCMIServer::prepareToStartGame() +{ gh = std::make_shared(this); switch(si->mode) { diff --git a/server/CVCMIServer.h b/server/CVCMIServer.h index e2f9d029c..0cffc2835 100644 --- a/server/CVCMIServer.h +++ b/server/CVCMIServer.h @@ -69,6 +69,7 @@ public: ~CVCMIServer(); void run(); bool prepareToStartGame(); + void prepareToRestart(); void startGameImmidiately(); void startAsyncAccept(); diff --git a/server/NetPacksLobbyServer.cpp b/server/NetPacksLobbyServer.cpp index 0e2ab7c92..5cea42e1d 100644 --- a/server/NetPacksLobbyServer.cpp +++ b/server/NetPacksLobbyServer.cpp @@ -161,6 +161,27 @@ bool LobbyGuiAction::checkClientPermissions(CVCMIServer * srv) const return srv->isClientHost(c->connectionID); } +bool LobbyEndGame::checkClientPermissions(CVCMIServer * srv) const +{ + return srv->isClientHost(c->connectionID); +} + +bool LobbyEndGame::applyOnServer(CVCMIServer * srv) +{ + srv->prepareToRestart(); + return true; +} + +void LobbyEndGame::applyOnServerAfterAnnounce(CVCMIServer * srv) +{ + boost::unique_lock stateLock(srv->stateMutex); + for(auto & c : srv->connections) + { + c->enterLobbyConnectionMode(); + c->disableStackSendingByID(); + } +} + bool LobbyStartGame::checkClientPermissions(CVCMIServer * srv) const { return srv->isClientHost(c->connectionID);