浏览代码

Progress on server side for rmg

nordsoft 2 年之前
父节点
当前提交
584dd20943

+ 1 - 1
client/LobbyClientNetPackVisitors.h

@@ -52,7 +52,7 @@ public:
 	virtual void visitLobbyClientDisconnected(LobbyClientDisconnected & pack) override;
 	virtual void visitLobbyClientDisconnected(LobbyClientDisconnected & pack) override;
 	virtual void visitLobbyChatMessage(LobbyChatMessage & pack) override;
 	virtual void visitLobbyChatMessage(LobbyChatMessage & pack) override;
 	virtual void visitLobbyGuiAction(LobbyGuiAction & pack) override;
 	virtual void visitLobbyGuiAction(LobbyGuiAction & pack) override;
-	virtual void visitLobbyStartGame(LobbyStartGame & pack) override;
+	virtual void visitLobbyLoadProgress(LobbyLoadProgress & pack) override;
 	virtual void visitLobbyUpdateState(LobbyUpdateState & pack) override;
 	virtual void visitLobbyUpdateState(LobbyUpdateState & pack) override;
 	virtual void visitLobbyShowMessage(LobbyShowMessage & pack) override;
 	virtual void visitLobbyShowMessage(LobbyShowMessage & pack) override;
 };
 };

+ 9 - 7
client/NetPacksLobbyClient.cpp

@@ -59,6 +59,9 @@ void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyClientDisconnected(LobbyClient
 
 
 void ApplyOnLobbyScreenNetPackVisitor::visitLobbyClientDisconnected(LobbyClientDisconnected & pack)
 void ApplyOnLobbyScreenNetPackVisitor::visitLobbyClientDisconnected(LobbyClientDisconnected & pack)
 {
 {
+	if(auto w = GH.windows().topWindow<CLoadingScreen>())
+		GH.windows().popWindow(w);
+	
 	if(GH.windows().count() > 0)
 	if(GH.windows().count() > 0)
 		GH.windows().popWindows(1);
 		GH.windows().popWindows(1);
 }
 }
@@ -122,16 +125,15 @@ void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyStartGame(LobbyStartGame & pac
 		handler.si = pack.initializedStartInfo;
 		handler.si = pack.initializedStartInfo;
 		handler.si->mode = modeBackup;
 		handler.si->mode = modeBackup;
 	}
 	}
-	if(settings["session"]["headless"].Bool())
-		handler.startGameplay(pack.initializedGameState);
+	handler.startGameplay(pack.initializedGameState);
 }
 }
 
 
-void ApplyOnLobbyScreenNetPackVisitor::visitLobbyStartGame(LobbyStartGame & pack)
+void ApplyOnLobbyScreenNetPackVisitor::visitLobbyLoadProgress(LobbyLoadProgress & pack)
 {
 {
-	if(pack.clientId != -1 && pack.clientId != handler.c->connectionID)
-		return;
-	
-	GH.windows().createAndPushWindow<CLoadingScreen>(std::bind(&CServerHandler::startGameplay, &handler, pack.initializedGameState));
+	if(auto w = GH.windows().topWindow<CLoadingScreen>())
+		w->set(pack.progress);
+	else
+		GH.windows().createAndPushWindow<CLoadingScreen>();
 }
 }
 
 
 void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyUpdateState(LobbyUpdateState & pack)
 void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyUpdateState(LobbyUpdateState & pack)

+ 2 - 3
client/mainmenu/CMainMenu.cpp

@@ -582,15 +582,14 @@ void CSimpleJoinScreen::connectThread(const std::string & addr, ui16 port)
 	});
 	});
 }
 }
 
 
-CLoadingScreen::CLoadingScreen(std::function<void()> loader)
-	: CWindowObject(BORDERED, getBackground()), loadingThread(loader)
+CLoadingScreen::CLoadingScreen()
+	: CWindowObject(BORDERED, getBackground())
 {
 {
 	CCS->musich->stopMusic(5000);
 	CCS->musich->stopMusic(5000);
 }
 }
 
 
 CLoadingScreen::~CLoadingScreen()
 CLoadingScreen::~CLoadingScreen()
 {
 {
-	loadingThread.join();
 }
 }
 
 
 void CLoadingScreen::showAll(Canvas & to)
 void CLoadingScreen::showAll(Canvas & to)

+ 4 - 5
client/mainmenu/CMainMenu.h

@@ -11,6 +11,7 @@
 
 
 #include "../windows/CWindowObject.h"
 #include "../windows/CWindowObject.h"
 #include "../../lib/JsonNode.h"
 #include "../../lib/JsonNode.h"
+#include "../../lib/LoadProgress.h"
 
 
 VCMI_LIB_NAMESPACE_BEGIN
 VCMI_LIB_NAMESPACE_BEGIN
 
 
@@ -178,14 +179,12 @@ public:
 	CSimpleJoinScreen(bool host = true);
 	CSimpleJoinScreen(bool host = true);
 };
 };
 
 
-class CLoadingScreen : public CWindowObject
+class CLoadingScreen : virtual public CWindowObject, virtual public Load::Progress
 {
 {
-	boost::thread loadingThread;
-
 	std::string getBackground();
 	std::string getBackground();
 
 
-public:
-	CLoadingScreen(std::function<void()> loader);
+public:	
+	CLoadingScreen();
 	~CLoadingScreen();
 	~CLoadingScreen();
 
 
 	void showAll(Canvas & to) override;
 	void showAll(Canvas & to) override;

+ 1 - 0
lib/NetPackVisitor.h

@@ -145,6 +145,7 @@ public:
 	virtual void visitLobbyClientDisconnected(LobbyClientDisconnected & pack) {}
 	virtual void visitLobbyClientDisconnected(LobbyClientDisconnected & pack) {}
 	virtual void visitLobbyChatMessage(LobbyChatMessage & pack) {}
 	virtual void visitLobbyChatMessage(LobbyChatMessage & pack) {}
 	virtual void visitLobbyGuiAction(LobbyGuiAction & pack) {}
 	virtual void visitLobbyGuiAction(LobbyGuiAction & pack) {}
+	virtual void visitLobbyLoadProgress(LobbyLoadProgress & pack) {}
 	virtual void visitLobbyEndGame(LobbyEndGame & pack) {}
 	virtual void visitLobbyEndGame(LobbyEndGame & pack) {}
 	virtual void visitLobbyStartGame(LobbyStartGame & pack) {}
 	virtual void visitLobbyStartGame(LobbyStartGame & pack) {}
 	virtual void visitLobbyChangeHost(LobbyChangeHost & pack) {}
 	virtual void visitLobbyChangeHost(LobbyChangeHost & pack) {}

+ 5 - 0
lib/NetPacksLib.cpp

@@ -693,6 +693,11 @@ void LobbyGuiAction::visitTyped(ICPackVisitor & visitor)
 	visitor.visitLobbyGuiAction(*this);
 	visitor.visitLobbyGuiAction(*this);
 }
 }
 
 
+void LobbyLoadProgress::visitTyped(ICPackVisitor & visitor)
+{
+	visitor.visitLobbyLoadProgress(*this);
+}
+
 void LobbyEndGame::visitTyped(ICPackVisitor & visitor)
 void LobbyEndGame::visitTyped(ICPackVisitor & visitor)
 {
 {
 	visitor.visitLobbyEndGame(*this);
 	visitor.visitLobbyEndGame(*this);

+ 12 - 0
lib/NetPacksLobby.h

@@ -99,6 +99,18 @@ struct DLL_LINKAGE LobbyGuiAction : public CLobbyPackToPropagate
 	}
 	}
 };
 };
 
 
+struct DLL_LINKAGE LobbyLoadProgress : public CLobbyPackToPropagate
+{
+	unsigned char progress;
+	
+	virtual void visitTyped(ICPackVisitor & visitor) override;
+
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & progress;
+	}
+};
+
 struct DLL_LINKAGE LobbyEndGame : public CLobbyPackToPropagate
 struct DLL_LINKAGE LobbyEndGame : public CLobbyPackToPropagate
 {
 {
 	bool closeConnection = false, restart = false;
 	bool closeConnection = false, restart = false;

+ 5 - 3
lib/gameState/CGameState.cpp

@@ -404,7 +404,7 @@ void CGameState::preInit(Services * services)
 	this->services = services;
 	this->services = services;
 }
 }
 
 
-void CGameState::init(const IMapService * mapService, StartInfo * si, bool allowSavingRandomMap)
+void CGameState::init(const IMapService * mapService, StartInfo * si, bool allowSavingRandomMap, Load::Progress * progressTracking)
 {
 {
 	preInitAuto();
 	preInitAuto();
 	logGlobal->info("\tUsing random seed: %d", si->seedToBeUsed);
 	logGlobal->info("\tUsing random seed: %d", si->seedToBeUsed);
@@ -416,7 +416,7 @@ void CGameState::init(const IMapService * mapService, StartInfo * si, bool allow
 	switch(scenarioOps->mode)
 	switch(scenarioOps->mode)
 	{
 	{
 	case StartInfo::NEW_GAME:
 	case StartInfo::NEW_GAME:
-		initNewGame(mapService, allowSavingRandomMap);
+		initNewGame(mapService, allowSavingRandomMap, progressTracking);
 		break;
 		break;
 	case StartInfo::CAMPAIGN:
 	case StartInfo::CAMPAIGN:
 		initCampaign();
 		initCampaign();
@@ -535,7 +535,7 @@ void CGameState::preInitAuto()
 	}
 	}
 }
 }
 
 
-void CGameState::initNewGame(const IMapService * mapService, bool allowSavingRandomMap)
+void CGameState::initNewGame(const IMapService * mapService, bool allowSavingRandomMap, Load::Progress * progressTracking)
 {
 {
 	if(scenarioOps->createRandomMap())
 	if(scenarioOps->createRandomMap())
 	{
 	{
@@ -544,8 +544,10 @@ void CGameState::initNewGame(const IMapService * mapService, bool allowSavingRan
 
 
 		// Gen map
 		// Gen map
 		CMapGenerator mapGenerator(*scenarioOps->mapGenOptions, scenarioOps->seedToBeUsed);
 		CMapGenerator mapGenerator(*scenarioOps->mapGenOptions, scenarioOps->seedToBeUsed);
+		progressTracking = &mapGenerator;
 
 
 		std::unique_ptr<CMap> randomMap = mapGenerator.generate();
 		std::unique_ptr<CMap> randomMap = mapGenerator.generate();
+		progressTracking = nullptr;
 
 
 		if(allowSavingRandomMap)
 		if(allowSavingRandomMap)
 		{
 		{

+ 3 - 2
lib/gameState/CGameState.h

@@ -11,6 +11,7 @@
 
 
 #include "bonuses/CBonusSystemNode.h"
 #include "bonuses/CBonusSystemNode.h"
 #include "IGameCallback.h"
 #include "IGameCallback.h"
+#include "LoadProgress.h"
 
 
 namespace boost
 namespace boost
 {
 {
@@ -89,7 +90,7 @@ public:
 
 
 	void preInit(Services * services);
 	void preInit(Services * services);
 
 
-	void init(const IMapService * mapService, StartInfo * si, bool allowSavingRandomMap = false);
+	void init(const IMapService * mapService, StartInfo * si, bool allowSavingRandomMap = false, Load::Progress * progressTracking = nullptr);
 	void updateOnLoad(StartInfo * si);
 	void updateOnLoad(StartInfo * si);
 
 
 	ConstTransitivePtr<StartInfo> scenarioOps, initialOpts; //second one is a copy of settings received from pregame (not randomized)
 	ConstTransitivePtr<StartInfo> scenarioOps, initialOpts; //second one is a copy of settings received from pregame (not randomized)
@@ -166,7 +167,7 @@ public:
 private:
 private:
 	// ----- initialization -----
 	// ----- initialization -----
 	void preInitAuto();
 	void preInitAuto();
-	void initNewGame(const IMapService * mapService, bool allowSavingRandomMap);
+	void initNewGame(const IMapService * mapService, bool allowSavingRandomMap, Load::Progress * progressTracking = nullptr);
 	void checkMapChecksum();
 	void checkMapChecksum();
 	void initGlobalBonuses();
 	void initGlobalBonuses();
 	void initGrailPosition();
 	void initGrailPosition();

+ 1 - 0
lib/registerTypes/RegisterTypes.h

@@ -379,6 +379,7 @@ void registerTypesLobbyPacks(Serializer &s)
 	s.template registerType<CLobbyPackToPropagate, LobbyChatMessage>();
 	s.template registerType<CLobbyPackToPropagate, LobbyChatMessage>();
 	// Only host client send
 	// Only host client send
 	s.template registerType<CLobbyPackToPropagate, LobbyGuiAction>();
 	s.template registerType<CLobbyPackToPropagate, LobbyGuiAction>();
+	s.template registerType<CLobbyPackToPropagate, LobbyLoadProgress>();
 	s.template registerType<CLobbyPackToPropagate, LobbyEndGame>();
 	s.template registerType<CLobbyPackToPropagate, LobbyEndGame>();
 	s.template registerType<CLobbyPackToPropagate, LobbyStartGame>();
 	s.template registerType<CLobbyPackToPropagate, LobbyStartGame>();
 	s.template registerType<CLobbyPackToPropagate, LobbyChangeHost>();
 	s.template registerType<CLobbyPackToPropagate, LobbyChangeHost>();

+ 2 - 2
server/CGameHandler.cpp

@@ -1599,7 +1599,7 @@ void CGameHandler::reinitScripting()
 #endif
 #endif
 }
 }
 
 
-void CGameHandler::init(StartInfo *si)
+void CGameHandler::init(StartInfo *si, Load::Progress * progressTracking)
 {
 {
 	if (si->seedToBeUsed == 0)
 	if (si->seedToBeUsed == 0)
 	{
 	{
@@ -1609,7 +1609,7 @@ void CGameHandler::init(StartInfo *si)
 	gs = new CGameState();
 	gs = new CGameState();
 	gs->preInit(VLC);
 	gs->preInit(VLC);
 	logGlobal->info("Gamestate created!");
 	logGlobal->info("Gamestate created!");
-	gs->init(&mapService, si);
+	gs->init(&mapService, si, false, progressTracking);
 	logGlobal->info("Gamestate initialized!");
 	logGlobal->info("Gamestate initialized!");
 
 
 	// reset seed, so that clients can't predict any following random values
 	// reset seed, so that clients can't predict any following random values

+ 2 - 1
server/CGameHandler.h

@@ -15,6 +15,7 @@
 #include "../lib/IGameCallback.h"
 #include "../lib/IGameCallback.h"
 #include "../lib/battle/CBattleInfoCallback.h"
 #include "../lib/battle/CBattleInfoCallback.h"
 #include "../lib/battle/BattleAction.h"
 #include "../lib/battle/BattleAction.h"
+#include "../lib/LoadProgress.h"
 #include "../lib/ScriptHandler.h"
 #include "../lib/ScriptHandler.h"
 #include "CQuery.h"
 #include "CQuery.h"
 
 
@@ -236,7 +237,7 @@ public:
 	void expGiven(const CGHeroInstance *hero); //triggers needed level-ups, handles also commander of this hero
 	void expGiven(const CGHeroInstance *hero); //triggers needed level-ups, handles also commander of this hero
 	//////////////////////////////////////////////////////////////////////////
 	//////////////////////////////////////////////////////////////////////////
 
 
-	void init(StartInfo *si);
+	void init(StartInfo *si, Load::Progress * progressTracking = nullptr);
 	void handleClientDisconnection(std::shared_ptr<CConnection> c);
 	void handleClientDisconnection(std::shared_ptr<CConnection> c);
 	void handleReceivedPack(CPackForServer * pack);
 	void handleReceivedPack(CPackForServer * pack);
 	PlayerColor getPlayerAt(std::shared_ptr<CConnection> c) const;
 	PlayerColor getPlayerAt(std::shared_ptr<CConnection> c) const;

+ 24 - 2
server/CVCMIServer.cpp

@@ -279,6 +279,24 @@ void CVCMIServer::prepareToRestart()
 
 
 bool CVCMIServer::prepareToStartGame()
 bool CVCMIServer::prepareToStartGame()
 {
 {
+	Load::Progress * progressTracking = nullptr;
+	bool progressTrackingFinished = false;
+	std::thread progressTrackingThread([this, &progressTracking, &progressTrackingFinished](){
+		while(!progressTrackingFinished)
+		{
+			if(progressTracking)
+			{
+				boost::unique_lock<boost::recursive_mutex> queueLock(mx);
+				std::unique_ptr<LobbyLoadProgress> loadProgress(new LobbyLoadProgress);
+				loadProgress->progress = progressTracking->get();
+				addToAnnounceQueue(std::move(loadProgress));
+			}
+			std::this_thread::sleep_for(std::chrono::milliseconds(100));
+		}
+		progressTrackingFinished = false;
+	});
+	progressTrackingThread.detach();
+	
 	gh = std::make_shared<CGameHandler>(this);
 	gh = std::make_shared<CGameHandler>(this);
 	switch(si->mode)
 	switch(si->mode)
 	{
 	{
@@ -286,12 +304,12 @@ bool CVCMIServer::prepareToStartGame()
 		logNetwork->info("Preparing to start new campaign");
 		logNetwork->info("Preparing to start new campaign");
 		si->campState->setCurrentMap(campaignMap);
 		si->campState->setCurrentMap(campaignMap);
 		si->campState->setCurrentMapBonus(campaignBonus);
 		si->campState->setCurrentMapBonus(campaignBonus);
-		gh->init(si.get());
+		gh->init(si.get(), progressTracking);
 		break;
 		break;
 
 
 	case StartInfo::NEW_GAME:
 	case StartInfo::NEW_GAME:
 		logNetwork->info("Preparing to start new game");
 		logNetwork->info("Preparing to start new game");
-		gh->init(si.get());
+		gh->init(si.get(), progressTracking);
 		break;
 		break;
 
 
 	case StartInfo::LOAD_GAME:
 	case StartInfo::LOAD_GAME:
@@ -305,6 +323,10 @@ bool CVCMIServer::prepareToStartGame()
 		break;
 		break;
 	}
 	}
 	
 	
+	progressTrackingFinished = true;
+	while(progressTrackingFinished)
+		continue;
+	
 	state = EServerState::GAMEPLAY_STARTING;
 	state = EServerState::GAMEPLAY_STARTING;
 	return true;
 	return true;
 }
 }

+ 4 - 0
server/NetPacksLobbyServer.cpp

@@ -289,6 +289,10 @@ void ApplyOnServerNetPackVisitor::visitLobbyStartGame(LobbyStartGame & pack)
 		result = false;
 		result = false;
 		return;
 		return;
 	}
 	}
+	// Announce loading
+	std::unique_ptr<LobbyLoadProgress> loadProgress(new LobbyLoadProgress);
+	srv.addToAnnounceQueue(std::move(loadProgress));
+	
 	// Server will prepare gamestate and we announce StartInfo to clients
 	// Server will prepare gamestate and we announce StartInfo to clients
 	if(!srv.prepareToStartGame())
 	if(!srv.prepareToStartGame())
 	{
 	{