Просмотр исходного кода

Do not start listening for connections in single-player games

Ivan Savenko 8 месяцев назад
Родитель
Сommit
048fc503c3

+ 1 - 1
client/CServerHandler.cpp

@@ -186,7 +186,7 @@ void CServerHandler::startLocalServerAndConnect(bool connectToLobby)
 	si->difficulty = lastDifficulty.Integer();
 
 	logNetwork->trace("\tStarting local server");
-	uint16_t srvport = serverRunner->start(getLocalPort(), connectToLobby, si);
+	uint16_t srvport = serverRunner->start(getLocalPort(), loadMode == ELoadMode::MULTI, connectToLobby, si);
 	logNetwork->trace("\tConnecting to local server");
 	connectToServer(getLocalHostname(), srvport);
 	logNetwork->trace("\tWaiting for connection");

+ 4 - 4
client/ServerRunner.cpp

@@ -34,7 +34,7 @@
 ServerThreadRunner::ServerThreadRunner() = default;
 ServerThreadRunner::~ServerThreadRunner() = default;
 
-uint16_t ServerThreadRunner::start(uint16_t cfgport, bool connectToLobby, std::shared_ptr<StartInfo> startingInfo)
+uint16_t ServerThreadRunner::start(uint16_t cfgport, bool listenForConnections, bool connectToLobby, std::shared_ptr<StartInfo> startingInfo)
 {
 	// cfgport may be 0 -- the real port is returned after calling prepare()
 	server = std::make_unique<CVCMIServer>(cfgport, true);
@@ -46,9 +46,9 @@ uint16_t ServerThreadRunner::start(uint16_t cfgport, bool connectToLobby, std::s
 
 	std::promise<uint16_t> promise;
 
-	threadRunLocalServer = boost::thread([this, connectToLobby, &promise]{
+	threadRunLocalServer = boost::thread([this, connectToLobby, listenForConnections, &promise]{
 		setThreadName("runServer");
-		uint16_t port = server->prepare(connectToLobby);
+		uint16_t port = server->prepare(connectToLobby, listenForConnections);
 		promise.set_value(port);
 		server->run();
 	});
@@ -100,7 +100,7 @@ int ServerProcessRunner::exitCode()
 	return child->exit_code();
 }
 
-uint16_t ServerProcessRunner::start(uint16_t port, bool connectToLobby, std::shared_ptr<StartInfo> startingInfo)
+uint16_t ServerProcessRunner::start(uint16_t port, bool listenForConnections, bool connectToLobby, std::shared_ptr<StartInfo> startingInfo)
 {
 	boost::filesystem::path serverPath = VCMIDirs::get().serverPath();
 	boost::filesystem::path logPath = VCMIDirs::get().userLogsPath() / "server_log.txt";

+ 3 - 3
client/ServerRunner.h

@@ -22,7 +22,7 @@ class CVCMIServer;
 class IServerRunner
 {
 public:
-	virtual uint16_t start(uint16_t port, bool connectToLobby, std::shared_ptr<StartInfo> startingInfo) = 0;
+	virtual uint16_t start(uint16_t port, bool listenForConnections, bool connectToLobby, std::shared_ptr<StartInfo> startingInfo) = 0;
 	virtual void shutdown() = 0;
 	virtual void wait() = 0;
 	virtual int exitCode() = 0;
@@ -38,7 +38,7 @@ class ServerThreadRunner final : public IServerRunner, boost::noncopyable
 	std::unique_ptr<CVCMIServer> server;
 	boost::thread threadRunLocalServer;
 public:
-	uint16_t start(uint16_t port, bool connectToLobby, std::shared_ptr<StartInfo> startingInfo) override;
+	uint16_t start(uint16_t port, bool listenForConnections, bool connectToLobby, std::shared_ptr<StartInfo> startingInfo) override;
 	void shutdown() override;
 	void wait() override;
 	int exitCode() override;
@@ -75,7 +75,7 @@ class ServerProcessRunner final : public IServerRunner, boost::noncopyable
 	std::unique_ptr<boost::process::child> child;
 
 public:
-	uint16_t start(uint16_t port, bool connectToLobby, std::shared_ptr<StartInfo> startingInfo) override;
+	uint16_t start(uint16_t port, bool listenForConnections, bool connectToLobby, std::shared_ptr<StartInfo> startingInfo) override;
 	void shutdown() override;
 	void wait() override;
 	int exitCode() override;

+ 23 - 16
server/CVCMIServer.cpp

@@ -80,26 +80,33 @@ CVCMIServer::CVCMIServer(uint16_t port, bool runByClient)
 
 CVCMIServer::~CVCMIServer() = default;
 
-uint16_t CVCMIServer::prepare(bool connectToLobby) {
+uint16_t CVCMIServer::prepare(bool connectToLobby, bool listenForConnections) {
 	if(connectToLobby) {
 		lobbyProcessor = std::make_unique<GlobalLobbyProcessor>(*this);
 		return 0;
 	} else {
-		return startAcceptingIncomingConnections();
+		return startAcceptingIncomingConnections(listenForConnections);
 	}
 }
 
-uint16_t CVCMIServer::startAcceptingIncomingConnections()
+uint16_t CVCMIServer::startAcceptingIncomingConnections(bool listenForConnections)
 {
+	networkServer = networkHandler->createServerTCP(*this);
+
 	port
 		? logNetwork->info("Port %d will be used", port)
 		: logNetwork->info("Randomly assigned port will be used");
 
 	// config port may be 0 => srvport will contain the OS-assigned port value
-	networkServer = networkHandler->createServerTCP(*this);
-	auto srvport = networkServer->start(port);
-	logNetwork->info("Listening for connections at port %d", srvport);
-	return srvport;
+
+	if (listenForConnections)
+	{
+		auto srvport = networkServer->start(port);
+		logNetwork->info("Listening for connections at port %d", srvport);
+		return srvport;
+	}
+	else
+		return 0;
 }
 
 void CVCMIServer::onNewConnection(const std::shared_ptr<INetworkConnection> & connection)
@@ -206,7 +213,7 @@ void CVCMIServer::prepareToRestart()
 		campaignMap = si->campState->currentScenario().value_or(CampaignScenarioID(0));
 		campaignBonus = si->campState->getBonusID(campaignMap).value_or(-1);
 	}
-	
+
 	for(auto activeConnection : activeConnections)
 		activeConnection->enterLobbyConnectionMode();
 
@@ -239,7 +246,7 @@ bool CVCMIServer::prepareToStartGame()
 			boost::this_thread::sleep(boost::posix_time::milliseconds(50));
 		}
 	});
-	
+
 	gh = std::make_shared<CGameHandler>(this);
 	switch(si->mode)
 	{
@@ -273,10 +280,10 @@ bool CVCMIServer::prepareToStartGame()
 		assert(0);
 		break;
 	}
-	
+
 	current.finish();
 	progressTrackingThread.join();
-	
+
 	return true;
 }
 
@@ -398,7 +405,7 @@ void CVCMIServer::clientConnected(std::shared_ptr<CConnection> c, std::vector<st
 	}
 
 	logNetwork->info("Connection with client %d established. UUID: %s", c->connectionID, c->uuid);
-	
+
 	for(auto & name : names)
 	{
 		logNetwork->info("Client %d player: %s", c->connectionID, name);
@@ -479,22 +486,22 @@ void CVCMIServer::reconnectPlayer(int connId)
 {
 	PlayerReinitInterface startAiPack;
 	startAiPack.playerConnectionId = connId;
-	
+
 	if(gh && si && getState() == EServerState::GAMEPLAY)
 	{
 		for(auto it = playerNames.begin(); it != playerNames.end(); ++it)
 		{
 			if(it->second.connection != connId)
 				continue;
-			
+
 			int id = it->first;
 			auto * playerSettings = si->getPlayersSettings(id);
 			if(!playerSettings)
 				continue;
-			
+
 			std::string messageText = boost::str(boost::format("%s (cid %d) is connected") % playerSettings->name % connId);
 			gh->playerMessages->broadcastMessage(playerSettings->color, messageText);
-			
+
 			startAiPack.players.push_back(playerSettings->color);
 		}
 

+ 2 - 2
server/CVCMIServer.h

@@ -63,7 +63,7 @@ public:
 	/// List of all active connections
 	std::vector<std::shared_ptr<CConnection>> activeConnections;
 
-	uint16_t prepare(bool connectToLobby);
+	uint16_t prepare(bool connectToLobby, bool listenForConnections);
 
 	// INetworkListener impl
 	void onDisconnected(const std::shared_ptr<INetworkConnection> & connection, const std::string & errorMessage) override;
@@ -82,7 +82,7 @@ public:
 	bool prepareToStartGame();
 	void prepareToRestart();
 	void startGameImmediately();
-	uint16_t startAcceptingIncomingConnections();
+	uint16_t startAcceptingIncomingConnections(bool listenForConnections);
 
 	void threadHandleClient(std::shared_ptr<CConnection> c);
 

+ 1 - 1
server/GlobalLobbyProcessor.cpp

@@ -99,7 +99,7 @@ void GlobalLobbyProcessor::receiveServerLoginSuccess(const JsonNode & json)
 {
 	// no-op, wait just for any new commands from lobby
 	logGlobal->info("Lobby: Successfully connected to lobby server");
-	owner.startAcceptingIncomingConnections();
+	owner.startAcceptingIncomingConnections(true);
 }
 
 void GlobalLobbyProcessor::receiveAccountJoinsRoom(const JsonNode & json)

+ 1 - 1
serverapp/EntryPoint.cpp

@@ -92,7 +92,7 @@ int main(int argc, const char * argv[])
 			port = opts["port"].as<uint16_t>();
 
 		CVCMIServer server(port, runByClient);
-		server.prepare(connectToLobby);
+		server.prepare(connectToLobby, true);
 		server.run();
 
 		// CVCMIServer destructor must be called here - before VLC cleanup