1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Progress on server side for rmg

This commit is contained in:
nordsoft 2023-08-21 05:06:58 +04:00
parent 2f5bd1423c
commit 584dd20943
14 changed files with 75 additions and 26 deletions

View File

@ -52,7 +52,7 @@ public:
virtual void visitLobbyClientDisconnected(LobbyClientDisconnected & pack) override;
virtual void visitLobbyChatMessage(LobbyChatMessage & 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 visitLobbyShowMessage(LobbyShowMessage & pack) override;
};

View File

@ -59,6 +59,9 @@ void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyClientDisconnected(LobbyClient
void ApplyOnLobbyScreenNetPackVisitor::visitLobbyClientDisconnected(LobbyClientDisconnected & pack)
{
if(auto w = GH.windows().topWindow<CLoadingScreen>())
GH.windows().popWindow(w);
if(GH.windows().count() > 0)
GH.windows().popWindows(1);
}
@ -122,16 +125,15 @@ void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyStartGame(LobbyStartGame & pac
handler.si = pack.initializedStartInfo;
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)

View File

@ -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);
}
CLoadingScreen::~CLoadingScreen()
{
loadingThread.join();
}
void CLoadingScreen::showAll(Canvas & to)

View File

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

View File

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

View File

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

View File

@ -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
{
bool closeConnection = false, restart = false;

View File

@ -404,7 +404,7 @@ void CGameState::preInit(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();
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)
{
case StartInfo::NEW_GAME:
initNewGame(mapService, allowSavingRandomMap);
initNewGame(mapService, allowSavingRandomMap, progressTracking);
break;
case StartInfo::CAMPAIGN:
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())
{
@ -544,8 +544,10 @@ void CGameState::initNewGame(const IMapService * mapService, bool allowSavingRan
// Gen map
CMapGenerator mapGenerator(*scenarioOps->mapGenOptions, scenarioOps->seedToBeUsed);
progressTracking = &mapGenerator;
std::unique_ptr<CMap> randomMap = mapGenerator.generate();
progressTracking = nullptr;
if(allowSavingRandomMap)
{

View File

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

View File

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

View File

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

View File

@ -15,6 +15,7 @@
#include "../lib/IGameCallback.h"
#include "../lib/battle/CBattleInfoCallback.h"
#include "../lib/battle/BattleAction.h"
#include "../lib/LoadProgress.h"
#include "../lib/ScriptHandler.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 init(StartInfo *si);
void init(StartInfo *si, Load::Progress * progressTracking = nullptr);
void handleClientDisconnection(std::shared_ptr<CConnection> c);
void handleReceivedPack(CPackForServer * pack);
PlayerColor getPlayerAt(std::shared_ptr<CConnection> c) const;

View File

@ -279,6 +279,24 @@ void CVCMIServer::prepareToRestart()
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);
switch(si->mode)
{
@ -286,12 +304,12 @@ bool CVCMIServer::prepareToStartGame()
logNetwork->info("Preparing to start new campaign");
si->campState->setCurrentMap(campaignMap);
si->campState->setCurrentMapBonus(campaignBonus);
gh->init(si.get());
gh->init(si.get(), progressTracking);
break;
case StartInfo::NEW_GAME:
logNetwork->info("Preparing to start new game");
gh->init(si.get());
gh->init(si.get(), progressTracking);
break;
case StartInfo::LOAD_GAME:
@ -305,6 +323,10 @@ bool CVCMIServer::prepareToStartGame()
break;
}
progressTrackingFinished = true;
while(progressTrackingFinished)
continue;
state = EServerState::GAMEPLAY_STARTING;
return true;
}

View File

@ -289,6 +289,10 @@ void ApplyOnServerNetPackVisitor::visitLobbyStartGame(LobbyStartGame & pack)
result = false;
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
if(!srv.prepareToStartGame())
{