mirror of
https://github.com/vcmi/vcmi.git
synced 2025-03-29 21:56:54 +02:00
Fixes and cleanup of game client network shutdown and restart
This commit is contained in:
parent
6eef197cea
commit
2c2bec791c
@ -131,12 +131,12 @@ CServerHandler::~CServerHandler()
|
||||
networkHandler->stop();
|
||||
try
|
||||
{
|
||||
threadNetwork->join();
|
||||
threadNetwork.join();
|
||||
}
|
||||
catch (const std::runtime_error & e)
|
||||
{
|
||||
logGlobal->error("Failed to shut down network thread! Reason: %s", e.what());
|
||||
assert(false);
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -144,17 +144,16 @@ CServerHandler::CServerHandler()
|
||||
: applier(std::make_unique<CApplier<CBaseForLobbyApply>>())
|
||||
, lobbyClient(std::make_unique<GlobalLobbyClient>())
|
||||
, networkHandler(INetworkHandler::createHandler())
|
||||
, threadNetwork(&CServerHandler::threadRunNetwork, this)
|
||||
, state(EClientState::NONE)
|
||||
, campaignStateToSend(nullptr)
|
||||
, screenType(ESelectionScreen::unknown)
|
||||
, serverMode(EServerMode::NONE)
|
||||
, loadMode(ELoadMode::NONE)
|
||||
, client(nullptr)
|
||||
, campaignServerRestartLock(false)
|
||||
{
|
||||
uuid = boost::uuids::to_string(boost::uuids::random_generator()());
|
||||
registerTypesLobbyPacks(*applier);
|
||||
threadNetwork = std::make_unique<boost::thread>(&CServerHandler::threadRunNetwork, this);
|
||||
}
|
||||
|
||||
void CServerHandler::threadRunNetwork()
|
||||
@ -192,8 +191,8 @@ GlobalLobbyClient & CServerHandler::getGlobalLobby()
|
||||
|
||||
void CServerHandler::startLocalServerAndConnect(bool connectToLobby)
|
||||
{
|
||||
if(threadRunLocalServer)
|
||||
threadRunLocalServer->join();
|
||||
if(threadRunLocalServer.joinable())
|
||||
threadRunLocalServer.join();
|
||||
|
||||
th->update();
|
||||
|
||||
@ -203,19 +202,17 @@ void CServerHandler::startLocalServerAndConnect(bool connectToLobby)
|
||||
if(connectToLobby)
|
||||
args.push_back("--lobby");
|
||||
|
||||
threadRunLocalServer = std::make_unique<boost::thread>([&cond, args, this] {
|
||||
threadRunLocalServer = boost::thread([&cond, args] {
|
||||
setThreadName("CVCMIServer");
|
||||
CVCMIServer::create(&cond, args);
|
||||
onServerFinished();
|
||||
});
|
||||
threadRunLocalServer->detach();
|
||||
#elif defined(VCMI_ANDROID)
|
||||
{
|
||||
CAndroidVMHelper envHelper;
|
||||
envHelper.callStaticVoidMethod(CAndroidVMHelper::NATIVE_METHODS_DEFAULT_CLASS, "startServer", true);
|
||||
}
|
||||
#else
|
||||
threadRunLocalServer = std::make_unique<boost::thread>(&CServerHandler::threadRunServer, this, connectToLobby); //runs server executable;
|
||||
threadRunLocalServer = boost::thread(&CServerHandler::threadRunServer, this, connectToLobby); //runs server executable;
|
||||
#endif
|
||||
logNetwork->trace("Setting up thread calling server: %d ms", th->getDiff());
|
||||
|
||||
@ -357,10 +354,7 @@ ui8 CServerHandler::myFirstId() const
|
||||
|
||||
bool CServerHandler::isServerLocal() const
|
||||
{
|
||||
if(threadRunLocalServer)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return threadRunLocalServer.joinable();
|
||||
}
|
||||
|
||||
bool CServerHandler::isHost() const
|
||||
@ -416,7 +410,10 @@ void CServerHandler::sendClientDisconnecting()
|
||||
{
|
||||
// FIXME: This is workaround needed to make sure client not trying to sent anything to non existed server
|
||||
if(state == EClientState::DISCONNECTING)
|
||||
{
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
|
||||
state = EClientState::DISCONNECTING;
|
||||
mapToStart = nullptr;
|
||||
@ -433,12 +430,8 @@ void CServerHandler::sendClientDisconnecting()
|
||||
logNetwork->info("Sent leaving signal to the server");
|
||||
}
|
||||
sendLobbyPack(lcd);
|
||||
|
||||
{
|
||||
// Network thread might be applying network pack at this moment
|
||||
auto unlockInterface = vstd::makeUnlockGuard(GH.interfaceMutex);
|
||||
c.reset();
|
||||
}
|
||||
c->getConnection()->close();
|
||||
c.reset();
|
||||
}
|
||||
|
||||
void CServerHandler::setCampaignState(std::shared_ptr<CampaignState> newCampaign)
|
||||
@ -585,9 +578,7 @@ void CServerHandler::sendRestartGame() const
|
||||
{
|
||||
GH.windows().createAndPushWindow<CLoadingScreen>();
|
||||
|
||||
LobbyEndGame endGame;
|
||||
endGame.closeConnection = false;
|
||||
endGame.restart = true;
|
||||
LobbyRestartGame endGame;
|
||||
sendLobbyPack(endGame);
|
||||
}
|
||||
|
||||
@ -676,40 +667,37 @@ void CServerHandler::startGameplay(VCMI_LIB_WRAP_NAMESPACE(CGameState) * gameSta
|
||||
state = EClientState::GAMEPLAY;
|
||||
}
|
||||
|
||||
void CServerHandler::endGameplay(bool closeConnection, bool restart)
|
||||
void CServerHandler::endGameplay()
|
||||
{
|
||||
if(closeConnection)
|
||||
{
|
||||
// Game is ending
|
||||
// Tell the network thread to reach a stable state
|
||||
CSH->sendClientDisconnecting();
|
||||
logNetwork->info("Closed connection.");
|
||||
}
|
||||
// Game is ending
|
||||
// Tell the network thread to reach a stable state
|
||||
CSH->sendClientDisconnecting();
|
||||
logNetwork->info("Closed connection.");
|
||||
|
||||
client->endGame();
|
||||
client.reset();
|
||||
|
||||
if(!restart)
|
||||
if(CMM)
|
||||
{
|
||||
if(CMM)
|
||||
{
|
||||
GH.curInt = CMM.get();
|
||||
CMM->enable();
|
||||
}
|
||||
else
|
||||
{
|
||||
GH.curInt = CMainMenu::create().get();
|
||||
}
|
||||
GH.curInt = CMM.get();
|
||||
CMM->enable();
|
||||
}
|
||||
|
||||
if(c)
|
||||
else
|
||||
{
|
||||
nextClient = std::make_unique<CClient>();
|
||||
c->setCallback(nextClient.get());
|
||||
c->enterLobbyConnectionMode();
|
||||
GH.curInt = CMainMenu::create().get();
|
||||
}
|
||||
}
|
||||
|
||||
void CServerHandler::restartGameplay()
|
||||
{
|
||||
client->endGame();
|
||||
client.reset();
|
||||
|
||||
nextClient = std::make_unique<CClient>();
|
||||
c->setCallback(nextClient.get());
|
||||
c->enterLobbyConnectionMode();
|
||||
}
|
||||
|
||||
void CServerHandler::startCampaignScenario(HighScoreParameter param, std::shared_ptr<CampaignState> cs)
|
||||
{
|
||||
std::shared_ptr<CampaignState> ourCampaign = cs;
|
||||
@ -728,7 +716,6 @@ void CServerHandler::startCampaignScenario(HighScoreParameter param, std::shared
|
||||
|
||||
GH.dispatchMainThread([ourCampaign, this]()
|
||||
{
|
||||
CSH->campaignServerRestartLock.set(true);
|
||||
CSH->endGameplay();
|
||||
|
||||
auto & epilogue = ourCampaign->scenario(*ourCampaign->lastScenario()).epilog;
|
||||
@ -751,13 +738,14 @@ void CServerHandler::startCampaignScenario(HighScoreParameter param, std::shared
|
||||
GH.windows().createAndPushWindow<CHighScoreInputScreen>(true, *highScoreCalc);
|
||||
}
|
||||
};
|
||||
|
||||
threadRunLocalServer.join();
|
||||
if(epilogue.hasPrologEpilog)
|
||||
{
|
||||
GH.windows().createAndPushWindow<CPrologEpilogVideo>(epilogue, finisher);
|
||||
}
|
||||
else
|
||||
{
|
||||
CSH->campaignServerRestartLock.waitUntil(false);
|
||||
finisher();
|
||||
}
|
||||
});
|
||||
@ -877,23 +865,19 @@ public:
|
||||
|
||||
void CServerHandler::onPacketReceived(const std::shared_ptr<INetworkConnection> &, const std::vector<std::byte> & message)
|
||||
{
|
||||
CPack * pack = c->retrievePack(message);
|
||||
if(state == EClientState::DISCONNECTING)
|
||||
{
|
||||
// FIXME: server shouldn't really send netpacks after it's tells client to disconnect
|
||||
// Though currently they'll be delivered and might cause crash.
|
||||
vstd::clear_pointer(pack);
|
||||
}
|
||||
else
|
||||
{
|
||||
ServerHandlerCPackVisitor visitor(*this);
|
||||
pack->visit(visitor);
|
||||
assert(0); //Should not be possible - socket must be closed at this point
|
||||
return;
|
||||
}
|
||||
|
||||
CPack * pack = c->retrievePack(message);
|
||||
ServerHandlerCPackVisitor visitor(*this);
|
||||
pack->visit(visitor);
|
||||
}
|
||||
|
||||
void CServerHandler::onDisconnected(const std::shared_ptr<INetworkConnection> & connection, const std::string & errorMessage)
|
||||
{
|
||||
assert(networkConnection == connection);
|
||||
networkConnection.reset();
|
||||
|
||||
if(state == EClientState::DISCONNECTING)
|
||||
@ -987,17 +971,9 @@ void CServerHandler::threadRunServer(bool connectToLobby)
|
||||
logNetwork->error("Error: server failed to close correctly or crashed!");
|
||||
logNetwork->error("Check %s for more info", logName);
|
||||
}
|
||||
onServerFinished();
|
||||
#endif
|
||||
}
|
||||
|
||||
void CServerHandler::onServerFinished()
|
||||
{
|
||||
threadRunLocalServer.reset();
|
||||
if (CSH)
|
||||
CSH->campaignServerRestartLock.setn(false);
|
||||
}
|
||||
|
||||
void CServerHandler::sendLobbyPack(const CPackForLobby & pack) const
|
||||
{
|
||||
if(state != EClientState::STARTING)
|
||||
|
@ -111,7 +111,6 @@ class CServerHandler final : public IServerAPI, public LobbyInfo, public INetwor
|
||||
/// required to correctly deserialize gamestate using client-side game callback
|
||||
std::unique_ptr<CClient> nextClient;
|
||||
|
||||
void onServerFinished();
|
||||
void sendLobbyPack(const CPackForLobby & pack) const override;
|
||||
|
||||
void onPacketReceived(const NetworkConnectionPtr &, const std::vector<std::byte> & message) override;
|
||||
@ -145,13 +144,11 @@ public:
|
||||
////////////////////
|
||||
|
||||
std::unique_ptr<CStopWatch> th;
|
||||
std::unique_ptr<boost::thread> threadRunLocalServer;
|
||||
std::unique_ptr<boost::thread> threadNetwork;
|
||||
boost::thread threadRunLocalServer;
|
||||
boost::thread threadNetwork;
|
||||
|
||||
std::unique_ptr<CClient> client;
|
||||
|
||||
CondSh<bool> campaignServerRestartLock;
|
||||
|
||||
CServerHandler();
|
||||
~CServerHandler();
|
||||
|
||||
@ -202,7 +199,8 @@ public:
|
||||
void debugStartTest(std::string filename, bool save = false);
|
||||
|
||||
void startGameplay(VCMI_LIB_WRAP_NAMESPACE(CGameState) * gameState = nullptr);
|
||||
void endGameplay(bool closeConnection = true, bool restart = false);
|
||||
void endGameplay();
|
||||
void restartGameplay();
|
||||
void startCampaignScenario(HighScoreParameter param, std::shared_ptr<CampaignState> cs = {});
|
||||
void showServerError(const std::string & txt) const;
|
||||
|
||||
|
@ -34,7 +34,7 @@ public:
|
||||
|
||||
virtual void visitLobbyClientConnected(LobbyClientConnected & pack) override;
|
||||
virtual void visitLobbyClientDisconnected(LobbyClientDisconnected & pack) override;
|
||||
virtual void visitLobbyEndGame(LobbyEndGame & pack) override;
|
||||
virtual void visitLobbyRestartGame(LobbyRestartGame & pack) override;
|
||||
virtual void visitLobbyStartGame(LobbyStartGame & pack) override;
|
||||
virtual void visitLobbyUpdateState(LobbyUpdateState & pack) override;
|
||||
};
|
||||
|
@ -133,18 +133,15 @@ void ApplyOnLobbyScreenNetPackVisitor::visitLobbyGuiAction(LobbyGuiAction & pack
|
||||
}
|
||||
}
|
||||
|
||||
void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyEndGame(LobbyEndGame & pack)
|
||||
void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyRestartGame(LobbyRestartGame & pack)
|
||||
{
|
||||
if(handler.state == EClientState::GAMEPLAY)
|
||||
{
|
||||
handler.endGameplay(pack.closeConnection, pack.restart);
|
||||
handler.restartGameplay();
|
||||
}
|
||||
|
||||
if(pack.restart)
|
||||
{
|
||||
if (handler.validateGameStart())
|
||||
handler.sendStartGame();
|
||||
}
|
||||
if (handler.validateGameStart())
|
||||
handler.sendStartGame();
|
||||
}
|
||||
|
||||
void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyStartGame(LobbyStartGame & pack)
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class NetworkConnection : public INetworkConnection, std::enable_shared_from_this<NetworkConnection>
|
||||
class NetworkConnection : public INetworkConnection, public std::enable_shared_from_this<NetworkConnection>
|
||||
{
|
||||
static const int messageHeaderSize = sizeof(uint32_t);
|
||||
static const int messageMaxSize = 64 * 1024 * 1024; // arbitrary size to prevent potential massive allocation if we receive garbage input
|
||||
|
@ -151,7 +151,7 @@ public:
|
||||
virtual void visitLobbyChatMessage(LobbyChatMessage & pack) {}
|
||||
virtual void visitLobbyGuiAction(LobbyGuiAction & pack) {}
|
||||
virtual void visitLobbyLoadProgress(LobbyLoadProgress & pack) {}
|
||||
virtual void visitLobbyEndGame(LobbyEndGame & pack) {}
|
||||
virtual void visitLobbyRestartGame(LobbyRestartGame & pack) {}
|
||||
virtual void visitLobbyStartGame(LobbyStartGame & pack) {}
|
||||
virtual void visitLobbyChangeHost(LobbyChangeHost & pack) {}
|
||||
virtual void visitLobbyUpdateState(LobbyUpdateState & pack) {}
|
||||
|
@ -708,9 +708,9 @@ void LobbyLoadProgress::visitTyped(ICPackVisitor & visitor)
|
||||
visitor.visitLobbyLoadProgress(*this);
|
||||
}
|
||||
|
||||
void LobbyEndGame::visitTyped(ICPackVisitor & visitor)
|
||||
void LobbyRestartGame::visitTyped(ICPackVisitor & visitor)
|
||||
{
|
||||
visitor.visitLobbyEndGame(*this);
|
||||
visitor.visitLobbyRestartGame(*this);
|
||||
}
|
||||
|
||||
void LobbyStartGame::visitTyped(ICPackVisitor & visitor)
|
||||
|
@ -111,17 +111,12 @@ struct DLL_LINKAGE LobbyLoadProgress : public CLobbyPackToPropagate
|
||||
}
|
||||
};
|
||||
|
||||
struct DLL_LINKAGE LobbyEndGame : public CLobbyPackToPropagate
|
||||
struct DLL_LINKAGE LobbyRestartGame : public CLobbyPackToPropagate
|
||||
{
|
||||
bool closeConnection = false;
|
||||
bool restart = false;
|
||||
|
||||
void visitTyped(ICPackVisitor & visitor) override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h)
|
||||
{
|
||||
h & closeConnection;
|
||||
h & restart;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -37,7 +37,7 @@ void registerTypesLobbyPacks(Serializer &s)
|
||||
// Only host client send
|
||||
s.template registerType<CLobbyPackToPropagate, LobbyGuiAction>();
|
||||
s.template registerType<CLobbyPackToPropagate, LobbyLoadProgress>();
|
||||
s.template registerType<CLobbyPackToPropagate, LobbyEndGame>();
|
||||
s.template registerType<CLobbyPackToPropagate, LobbyRestartGame>();
|
||||
s.template registerType<CLobbyPackToPropagate, LobbyStartGame>();
|
||||
s.template registerType<CLobbyPackToPropagate, LobbyChangeHost>();
|
||||
// Only server send
|
||||
|
@ -140,6 +140,7 @@ void CConnection::enterGameplayConnectionMode(CGameState * gs)
|
||||
|
||||
setCallback(gs->callback);
|
||||
packWriter->addStdVecItems(gs);
|
||||
packReader->addStdVecItems(gs);
|
||||
}
|
||||
|
||||
void CConnection::disableSmartPointerSerialization()
|
||||
|
@ -445,7 +445,10 @@ void CGameHandler::changeSecSkill(const CGHeroInstance * hero, SecondarySkill wh
|
||||
void CGameHandler::handleClientDisconnection(std::shared_ptr<CConnection> c)
|
||||
{
|
||||
if(lobby->getState() == EServerState::SHUTDOWN || !gs || !gs->scenarioOps)
|
||||
{
|
||||
assert(0); // game should have shut down before reaching this point!
|
||||
return;
|
||||
}
|
||||
|
||||
for(auto & playerConnections : connections)
|
||||
{
|
||||
@ -3609,7 +3612,7 @@ void CGameHandler::checkVictoryLossConditionsForPlayer(PlayerColor player)
|
||||
|
||||
if(p->human)
|
||||
{
|
||||
lobby->setState(EServerState::GAMEPLAY_ENDED);
|
||||
lobby->setState(EServerState::SHUTDOWN);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -117,9 +117,7 @@ public:
|
||||
};
|
||||
|
||||
CVCMIServer::CVCMIServer(boost::program_options::variables_map & opts)
|
||||
: restartGameplay(false)
|
||||
, state(EServerState::LOBBY)
|
||||
, currentClientId(1)
|
||||
: currentClientId(1)
|
||||
, currentPlayerId(1)
|
||||
, cmdLineOptions(opts)
|
||||
{
|
||||
@ -153,13 +151,14 @@ void CVCMIServer::startAcceptingIncomingConnections()
|
||||
|
||||
void CVCMIServer::onNewConnection(const std::shared_ptr<INetworkConnection> & connection)
|
||||
{
|
||||
if(state == EServerState::LOBBY)
|
||||
if(getState() == EServerState::LOBBY)
|
||||
{
|
||||
activeConnections.push_back(std::make_shared<CConnection>(connection));
|
||||
activeConnections.back()->enterLobbyConnectionMode();
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: reconnection support
|
||||
connection->close();
|
||||
}
|
||||
}
|
||||
@ -175,7 +174,11 @@ void CVCMIServer::onPacketReceived(const std::shared_ptr<INetworkConnection> & c
|
||||
|
||||
void CVCMIServer::setState(EServerState value)
|
||||
{
|
||||
assert(state != EServerState::SHUTDOWN); // do not attempt to restart dying server
|
||||
state = value;
|
||||
|
||||
if (state == EServerState::SHUTDOWN)
|
||||
networkHandler->stop();
|
||||
}
|
||||
|
||||
EServerState CVCMIServer::getState() const
|
||||
@ -208,7 +211,8 @@ void CVCMIServer::run()
|
||||
|
||||
void CVCMIServer::onTimer()
|
||||
{
|
||||
if (state != EServerState::GAMEPLAY)
|
||||
// we might receive onTimer call after transitioning from GAMEPLAY to LOBBY state, e.g. on game restart
|
||||
if (getState() != EServerState::GAMEPLAY)
|
||||
return;
|
||||
|
||||
static const auto serverUpdateInterval = std::chrono::milliseconds(100);
|
||||
@ -230,18 +234,20 @@ void CVCMIServer::onTimer()
|
||||
|
||||
void CVCMIServer::prepareToRestart()
|
||||
{
|
||||
if(state == EServerState::GAMEPLAY)
|
||||
if(getState() != EServerState::GAMEPLAY)
|
||||
{
|
||||
restartGameplay = true;
|
||||
* si = * gh->gs->initialOpts;
|
||||
si->seedToBeUsed = si->seedPostInit = 0;
|
||||
state = EServerState::LOBBY;
|
||||
if (si->campState)
|
||||
{
|
||||
assert(si->campState->currentScenario().has_value());
|
||||
campaignMap = si->campState->currentScenario().value_or(CampaignScenarioID(0));
|
||||
campaignBonus = si->campState->getBonusID(campaignMap).value_or(-1);
|
||||
}
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
|
||||
* si = * gh->gs->initialOpts;
|
||||
si->seedToBeUsed = si->seedPostInit = 0;
|
||||
setState(EServerState::LOBBY);
|
||||
if (si->campState)
|
||||
{
|
||||
assert(si->campState->currentScenario().has_value());
|
||||
campaignMap = si->campState->currentScenario().value_or(CampaignScenarioID(0));
|
||||
campaignBonus = si->campState->getBonusID(campaignMap).value_or(-1);
|
||||
}
|
||||
|
||||
for(auto c : activeConnections)
|
||||
@ -319,7 +325,7 @@ void CVCMIServer::startGameImmediately()
|
||||
c->enterGameplayConnectionMode(gh->gs);
|
||||
|
||||
gh->start(si->mode == EStartMode::LOAD_GAME);
|
||||
state = EServerState::GAMEPLAY;
|
||||
setState(EServerState::GAMEPLAY);
|
||||
lastTimerUpdateTime = gameplayStartTime = std::chrono::steady_clock::now();
|
||||
onTimer();
|
||||
}
|
||||
@ -333,12 +339,11 @@ void CVCMIServer::onDisconnected(const std::shared_ptr<INetworkConnection> & con
|
||||
|
||||
if(activeConnections.empty() || hostClientId == c->connectionID)
|
||||
{
|
||||
networkHandler->stop();
|
||||
state = EServerState::SHUTDOWN;
|
||||
setState(EServerState::SHUTDOWN);
|
||||
return;
|
||||
}
|
||||
|
||||
if(gh && state == EServerState::GAMEPLAY)
|
||||
if(gh && getState() == EServerState::GAMEPLAY)
|
||||
{
|
||||
gh->handleClientDisconnection(c);
|
||||
|
||||
@ -406,7 +411,7 @@ bool CVCMIServer::passHost(int toConnectionId)
|
||||
|
||||
void CVCMIServer::clientConnected(std::shared_ptr<CConnection> c, std::vector<std::string> & names, const std::string & uuid, EStartMode mode)
|
||||
{
|
||||
assert(state == EServerState::LOBBY);
|
||||
assert(getState() == EServerState::LOBBY);
|
||||
|
||||
c->connectionID = currentClientId++;
|
||||
|
||||
@ -446,13 +451,6 @@ void CVCMIServer::clientDisconnected(std::shared_ptr<CConnection> c)
|
||||
c->getConnection()->close();
|
||||
vstd::erase(activeConnections, c);
|
||||
|
||||
if(activeConnections.empty() || hostClientId == c->connectionID)
|
||||
{
|
||||
networkHandler->stop();
|
||||
state = EServerState::SHUTDOWN;
|
||||
return;
|
||||
}
|
||||
|
||||
// PlayerReinitInterface startAiPack;
|
||||
// startAiPack.playerConnectionId = PlayerSettings::PLAYER_AI;
|
||||
//
|
||||
@ -494,7 +492,7 @@ void CVCMIServer::reconnectPlayer(int connId)
|
||||
PlayerReinitInterface startAiPack;
|
||||
startAiPack.playerConnectionId = connId;
|
||||
|
||||
if(gh && si && state == EServerState::GAMEPLAY)
|
||||
if(gh && si && getState() == EServerState::GAMEPLAY)
|
||||
{
|
||||
for(auto it = playerNames.begin(); it != playerNames.end(); ++it)
|
||||
{
|
||||
|
@ -42,9 +42,7 @@ class GlobalLobbyProcessor;
|
||||
enum class EServerState : ui8
|
||||
{
|
||||
LOBBY,
|
||||
GAMEPLAY_STARTING,
|
||||
GAMEPLAY,
|
||||
GAMEPLAY_ENDED,
|
||||
SHUTDOWN
|
||||
};
|
||||
|
||||
@ -59,10 +57,8 @@ class CVCMIServer : public LobbyInfo, public INetworkServerListener, public INet
|
||||
|
||||
std::unique_ptr<INetworkHandler> networkHandler;
|
||||
|
||||
bool restartGameplay; // FIXME: this is just a hack
|
||||
|
||||
std::shared_ptr<CApplier<CBaseForServerApply>> applier;
|
||||
EServerState state;
|
||||
EServerState state = EServerState::LOBBY;
|
||||
|
||||
std::shared_ptr<CConnection> findConnection(const std::shared_ptr<INetworkConnection> &);
|
||||
|
||||
|
@ -31,7 +31,8 @@ void GlobalLobbyProcessor::onDisconnected(const std::shared_ptr<INetworkConnecti
|
||||
{
|
||||
if (connection == controlConnection)
|
||||
{
|
||||
throw std::runtime_error("Lost connection to a lobby server!");
|
||||
owner.setState(EServerState::SHUTDOWN);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -68,7 +69,7 @@ void GlobalLobbyProcessor::receiveOperationFailed(const JsonNode & json)
|
||||
{
|
||||
logGlobal->info("Lobby: Failed to login into a lobby server!");
|
||||
|
||||
throw std::runtime_error("Failed to login into a lobby server!");
|
||||
owner.setState(EServerState::SHUTDOWN);
|
||||
}
|
||||
|
||||
void GlobalLobbyProcessor::receiveLoginSuccess(const JsonNode & json)
|
||||
@ -91,7 +92,7 @@ void GlobalLobbyProcessor::receiveAccountJoinsRoom(const JsonNode & json)
|
||||
|
||||
void GlobalLobbyProcessor::onConnectionFailed(const std::string & errorMessage)
|
||||
{
|
||||
throw std::runtime_error("Failed to connect to a lobby server!");
|
||||
owner.setState(EServerState::SHUTDOWN);
|
||||
}
|
||||
|
||||
void GlobalLobbyProcessor::onConnectionEstablished(const std::shared_ptr<INetworkConnection> & connection)
|
||||
|
@ -31,7 +31,7 @@ public:
|
||||
virtual void visitForLobby(CPackForLobby & pack) override;
|
||||
virtual void visitLobbyClientConnected(LobbyClientConnected & pack) override;
|
||||
virtual void visitLobbyClientDisconnected(LobbyClientDisconnected & pack) override;
|
||||
virtual void visitLobbyEndGame(LobbyEndGame & pack) override;
|
||||
virtual void visitLobbyRestartGame(LobbyRestartGame & pack) override;
|
||||
virtual void visitLobbyStartGame(LobbyStartGame & pack) override;
|
||||
virtual void visitLobbyChangeHost(LobbyChangeHost & pack) override;
|
||||
virtual void visitLobbyChangePlayerOption(LobbyChangePlayerOption & pack) override;
|
||||
@ -53,7 +53,7 @@ public:
|
||||
virtual void visitForLobby(CPackForLobby & pack) override;
|
||||
virtual void visitLobbyClientConnected(LobbyClientConnected & pack) override;
|
||||
virtual void visitLobbyClientDisconnected(LobbyClientDisconnected & pack) override;
|
||||
virtual void visitLobbyEndGame(LobbyEndGame & pack) override;
|
||||
virtual void visitLobbyRestartGame(LobbyRestartGame & pack) override;
|
||||
virtual void visitLobbyStartGame(LobbyStartGame & pack) override;
|
||||
virtual void visitLobbyChangeHost(LobbyChangeHost & pack) override;
|
||||
};
|
||||
@ -81,7 +81,7 @@ public:
|
||||
virtual void visitLobbySetCampaign(LobbySetCampaign & pack) override;
|
||||
virtual void visitLobbySetCampaignMap(LobbySetCampaignMap & pack) override;
|
||||
virtual void visitLobbySetCampaignBonus(LobbySetCampaignBonus & pack) override;
|
||||
virtual void visitLobbyEndGame(LobbyEndGame & pack) override;
|
||||
virtual void visitLobbyRestartGame(LobbyRestartGame & pack) override;
|
||||
virtual void visitLobbyStartGame(LobbyStartGame & pack) override;
|
||||
virtual void visitLobbyChangeHost(LobbyChangeHost & pack) override;
|
||||
virtual void visitLobbyChangePlayerOption(LobbyChangePlayerOption & pack) override;
|
||||
|
@ -36,14 +36,7 @@ void ApplyOnServerAfterAnnounceNetPackVisitor::visitForLobby(CPackForLobby & pac
|
||||
|
||||
void ClientPermissionsCheckerNetPackVisitor::visitLobbyClientConnected(LobbyClientConnected & pack)
|
||||
{
|
||||
if(srv.getState() == EServerState::LOBBY)
|
||||
{
|
||||
result = true;
|
||||
return;
|
||||
}
|
||||
|
||||
result = false;
|
||||
return;
|
||||
result = srv.getState() == EServerState::LOBBY;
|
||||
}
|
||||
|
||||
void ApplyOnServerNetPackVisitor::visitLobbyClientConnected(LobbyClientConnected & pack)
|
||||
@ -197,19 +190,19 @@ void ClientPermissionsCheckerNetPackVisitor::visitLobbyGuiAction(LobbyGuiAction
|
||||
result = srv.isClientHost(pack.c->connectionID);
|
||||
}
|
||||
|
||||
void ClientPermissionsCheckerNetPackVisitor::visitLobbyEndGame(LobbyEndGame & pack)
|
||||
void ClientPermissionsCheckerNetPackVisitor::visitLobbyRestartGame(LobbyRestartGame & pack)
|
||||
{
|
||||
result = srv.isClientHost(pack.c->connectionID);
|
||||
}
|
||||
|
||||
void ApplyOnServerNetPackVisitor::visitLobbyEndGame(LobbyEndGame & pack)
|
||||
void ApplyOnServerNetPackVisitor::visitLobbyRestartGame(LobbyRestartGame & pack)
|
||||
{
|
||||
srv.prepareToRestart();
|
||||
|
||||
result = true;
|
||||
}
|
||||
|
||||
void ApplyOnServerAfterAnnounceNetPackVisitor::visitLobbyEndGame(LobbyEndGame & pack)
|
||||
void ApplyOnServerAfterAnnounceNetPackVisitor::visitLobbyRestartGame(LobbyRestartGame & pack)
|
||||
{
|
||||
for(auto & c : srv.activeConnections)
|
||||
c->enterLobbyConnectionMode();
|
||||
@ -241,8 +234,6 @@ void ApplyOnServerNetPackVisitor::visitLobbyStartGame(LobbyStartGame & pack)
|
||||
|
||||
pack.initializedStartInfo = std::make_shared<StartInfo>(*srv.gh->getStartInfo(true));
|
||||
pack.initializedGameState = srv.gh->gameState();
|
||||
|
||||
srv.setState(EServerState::GAMEPLAY_STARTING);
|
||||
result = true;
|
||||
}
|
||||
|
||||
|
@ -233,7 +233,7 @@ void TurnOrderProcessor::doStartNewDay()
|
||||
|
||||
if(!activePlayer)
|
||||
{
|
||||
gameHandler->gameLobby()->setState(EServerState::GAMEPLAY_ENDED);
|
||||
gameHandler->gameLobby()->setState(EServerState::SHUTDOWN);
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user